0
点赞
收藏
分享

微信扫一扫

Android 项目总结(View控件星空图控件)

笙烛 2022-01-09 阅读 171
public class StellarMap extends FrameLayout implements AnimationListener, OnTouchListener, OnGestureListener {

	private RandomLayout mHidenGroup;

	private RandomLayout mShownGroup;

	private Adapter mAdapter;
	private RandomLayout.Adapter mShownGroupAdapter;
	private RandomLayout.Adapter mHidenGroupAdapter;

	private int mShownGroupIndex;// 显示的组
	private int mHidenGroupIndex;// 隐藏的组
	private int mGroupCount;// 组数

	/** 动画 */
	private Animation mZoomInNearAnim;
	private Animation mZoomInAwayAnim;
	private Animation mZoomOutNearAnim;
	private Animation mZoomOutAwayAnim;

	private Animation mPanOutAnim;
	/** 手势识别器 */
	private GestureDetector mGestureDetector;

	/** 构造方法 */
	public StellarMap(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		init();
	}

	public StellarMap(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
	}

	public StellarMap(Context context) {
		super(context);
		init();
	}

	/** 初始化方法 */
	private void init() {
		mGroupCount = 0;
		mHidenGroupIndex = -1;
		mShownGroupIndex = -1;
		mHidenGroup = new RandomLayout(getContext());
		mShownGroup = new RandomLayout(getContext());

		addView(mHidenGroup, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
		mHidenGroup.setVisibility(View.GONE);
		addView(mShownGroup, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));

		mGestureDetector = new GestureDetector(getContext(), this);
		setOnTouchListener(this);
		//设置动画
		mZoomInNearAnim = AnimationUtil.createZoomInNearAnim();
		mZoomInNearAnim.setAnimationListener(this);
		mZoomInAwayAnim = AnimationUtil.createZoomInAwayAnim();
		mZoomInAwayAnim.setAnimationListener(this);
		mZoomOutNearAnim = AnimationUtil.createZoomOutNearAnim();
		mZoomOutNearAnim.setAnimationListener(this);
		mZoomOutAwayAnim = AnimationUtil.createZoomOutAwayAnim();
		mZoomOutAwayAnim.setAnimationListener(this);
	}

	/** 设置x和y方向的密度*/
	public void setRegularity(int xRegularity, int yRegularity) {
		mHidenGroup.setRegularity(xRegularity, yRegularity);
		mShownGroup.setRegularity(xRegularity, yRegularity);
	}

	private void setChildAdapter() {
		if (null == mAdapter) {
			return;
		}
		mHidenGroupAdapter = new RandomLayout.Adapter() {
			//取出本Adapter的View对象给HidenGroup的Adapter
			@Override
			public View getView(int position, View convertView) {
				return mAdapter.getView(mHidenGroupIndex, position, convertView);
			}

			@Override
			public int getCount() {
				return mAdapter.getCount(mHidenGroupIndex);
			}
		};
		mHidenGroup.setAdapter(mHidenGroupAdapter);

		mShownGroupAdapter = new RandomLayout.Adapter() {
			//取出本Adapter的View对象给ShownGroup的Adapter
			@Override
			public View getView(int position, View convertView) {
				return mAdapter.getView(mShownGroupIndex, position, convertView);
			}

			@Override
			public int getCount() {
				return mAdapter.getCount(mShownGroupIndex);
			}
		};
		mShownGroup.setAdapter(mShownGroupAdapter);
	}

	/** 设置本Adapter */
	public void setAdapter(Adapter adapter) {
		mAdapter = adapter;
		mGroupCount = mAdapter.getGroupCount();
		if (mGroupCount > 0) {
			mShownGroupIndex = 0;
		}
		setChildAdapter();
		setGroup(0, true);
	}

	/** 设置显示区域 */
	public void setInnerPadding(int paddingLeft, int paddingTop, int paddingRight, int paddingBottom) {
		mHidenGroup.setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom);
		mShownGroup.setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom);
	}

	/** 给指定的Group设置动画 */
	public void setGroup(int groupIndex, boolean playAnimation) {
		switchGroup(groupIndex, playAnimation, mZoomInNearAnim, mZoomInAwayAnim);
	}

	/** 获取当前显示的group角标 */
	public int getCurrentGroup() {
		return mShownGroupIndex;
	}

	/** 给Group设置动画入 */
	public void zoomIn() {
		final int nextGroupIndex = mAdapter.getNextGroupOnZoom(mShownGroupIndex, true);
		switchGroup(nextGroupIndex, true, mZoomInNearAnim, mZoomInAwayAnim);
	}

	/** 给Group设置出动画 */
	public void zoomOut() {
		final int nextGroupIndex = mAdapter.getNextGroupOnZoom(mShownGroupIndex, false);
		switchGroup(nextGroupIndex, true, mZoomOutNearAnim, mZoomOutAwayAnim);
	}

	/** 给下一个Group设置进出动画 */
	private void switchGroup(int newGroupIndex, boolean playAnimation, Animation inAnim, Animation outAnim) {
		if (newGroupIndex < 0 || newGroupIndex >= mGroupCount) {
			return;
		}
		//把当前显示Group角标设置为隐藏的
		mHidenGroupIndex = mShownGroupIndex;
		//把下一个Group角标设置为显示的
		mShownGroupIndex = newGroupIndex;
		// 交换两个Group
		RandomLayout temp = mShownGroup;
		mShownGroup = mHidenGroup;
		mShownGroup.setAdapter(mShownGroupAdapter);
		mHidenGroup = temp;
		mHidenGroup.setAdapter(mHidenGroupAdapter);
		//刷新显示的Group
		mShownGroup.refresh();
		//显示Group
		mShownGroup.setVisibility(View.VISIBLE);

		//启动动画
		if (playAnimation) {
			if (mShownGroup.hasLayouted()) {
				mShownGroup.startAnimation(inAnim);
			}
			mHidenGroup.startAnimation(outAnim);
		} else {
			mHidenGroup.setVisibility(View.GONE);
		}
	}

	// 重新分配显示区域
	public void redistribute() {
		mShownGroup.redistribute();
	}

	/** 动画监听 */
	@Override
	public void onAnimationStart(Animation animation) {
		// 当动画启动
	}

	@Override
	public void onAnimationEnd(Animation animation) {
		// 当动画结束
		if (animation == mZoomInAwayAnim || animation == mZoomOutAwayAnim || animation == mPanOutAnim) {
			mHidenGroup.setVisibility(View.GONE);
		}
	}

	@Override
	public void onAnimationRepeat(Animation animation) {
		// 当动画重复
	}

	/** 定位 */
	@Override
	public void onLayout(boolean changed, int l, int t, int r, int b) {
		//用以判断ShownGroup是否onLayout的变量
		boolean hasLayoutedBefore = mShownGroup.hasLayouted();
		super.onLayout(changed, l, t, r, b);
		if (!hasLayoutedBefore && mShownGroup.hasLayouted()) {
			mShownGroup.startAnimation(mZoomInNearAnim);//第一次layout的时候启动动画
		} else {
			mShownGroup.setVisibility(View.VISIBLE);
		}
	}

	/** 重写onTouch事件,把onTouch事件分配给手势识别 */
	@Override
	public boolean onTouch(View v, MotionEvent event) {
		return mGestureDetector.onTouchEvent(event);
	}

	/** 消费掉onDown事件 */
	@Override
	public boolean onDown(MotionEvent e) {
		return true;
	}

	/** 空实现 */
	@Override
	public void onShowPress(MotionEvent e) {
	}

	@Override
	public boolean onSingleTapUp(MotionEvent e) {
		return false;
	}

	@Override
	public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
		return false;
	}

	@Override
	public void onLongPress(MotionEvent e) {

	}

	@Override
	public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
		int centerX = getMeasuredWidth() / 2;
		int centerY = getMeasuredWidth() / 2;

		int x1 = (int) e1.getX() - centerX;
		int y1 = (int) e1.getY() - centerY;
		int x2 = (int) e2.getX() - centerX;
		int y2 = (int) e2.getY() - centerY;

		if ((x1 * x1 + y1 * y1) > (x2 * x2 + y2 * y2)) {
			zoomOut();
		} else {
			zoomIn();
		}
		return true;
	}

	/** 内部类、接口 */
	public static interface Adapter {
		public abstract int getGroupCount();

		public abstract int getCount(int group);

		public abstract View getView(int group, int position, View convertView);

		public abstract int getNextGroupOnZoom(int group, boolean isZoomIn);
	}
}

工具类

public class RandomLayout extends ViewGroup {

	private Random mRdm;
	/** X分布规则性,该值越高,子view在x方向的分布越规则、平均。最小值为1。 */
	private int mXRegularity;
	/** Y分布规则性,该值越高,子view在y方向的分布越规则、平均。最小值为1。 */
	private int mYRegularity;
	/** 区域个数 */
	private int mAreaCount;
	/** 区域的二维数组 */
	private int[][] mAreaDensity;
	/** 存放已经确定位置的View */
	private Set<View> mFixedViews;
	/** 提供子View的adapter */
	private Adapter mAdapter;
	/** 记录被回收的View,以便重复利用 */
	private List<View> mRecycledViews;
	/** 是否已经layout */
	private boolean mLayouted;
	/** 计算重叠时候的间距 */
	private int mOverlapAdd = 2;

	/** 构造方法 */
	public RandomLayout(Context context) {
		super(context);
		init();
	}

	/** 初始化方法 */
	private void init() {
		mLayouted = false;
		mRdm = new Random();
		setRegularity(1, 1);
		mFixedViews = new HashSet<View>();
		mRecycledViews = new LinkedList<View>();
	}

	public boolean hasLayouted() {
		return mLayouted;
	}

	/** 设置mXRegularity和mXRegularity,确定区域的个数 */
	public void setRegularity(int xRegularity, int yRegularity) {
		if (xRegularity > 1) {
			this.mXRegularity = xRegularity;
		} else {
			this.mXRegularity = 1;
		}
		if (yRegularity > 1) {
			this.mYRegularity = yRegularity;
		} else {
			this.mYRegularity = 1;
		}
		this.mAreaCount = mXRegularity * mYRegularity;//个数等于x方向的个数*y方向的个数
		this.mAreaDensity = new int[mYRegularity][mXRegularity];//存放区域的二维数组
	}

	/** 设置数据源 */
	public void setAdapter(Adapter adapter) {
		this.mAdapter = adapter;
	}

	/** 重新设置区域,把所有的区域记录都归0 */
	private void resetAllAreas() {
		mFixedViews.clear();
		for (int i = 0; i < mYRegularity; i++) {
			for (int j = 0; j < mXRegularity; j++) {
				mAreaDensity[i][j] = 0;
			}
		}
	}

	/** 把复用的View加入集合,新加入的放入集合第一个。 */
	private void pushRecycler(View scrapView) {
		if (null != scrapView) {
			mRecycledViews.add(0, scrapView);
		}
	}

	/** 取出复用的View,从集合的第一个位置取出 */
	private View popRecycler() {
		final int size = mRecycledViews.size();
		if (size > 0) {
			return mRecycledViews.remove(0);
		} else {
			return null;
		}
	}

	/** 产生子View,这个就是listView复用的简化版,但是原理一样 */
	private void generateChildren() {
		if (null == mAdapter) {
			return;
		}
		// 先把子View全部存入集合
		final int childCount = super.getChildCount();
		for (int i = childCount - 1; i >= 0; i--) {
			pushRecycler(super.getChildAt(i));
		}
		// 删除所有子View
		super.removeAllViewsInLayout();
		// 得到Adapter中的数据量
		final int count = mAdapter.getCount();
		for (int i = 0; i < count; i++) {
			//从集合中取出之前存入的子View
			View convertView = popRecycler();
			//把该子View作为adapter的getView的历史View传入,得到返回的View
			View newChild = mAdapter.getView(i, convertView);
			if (newChild != convertView) {//如果发生了复用,那么newChild应该等于convertView
				// 这说明没发生复用,所以重新把这个没用到的子View存入集合中
				pushRecycler(convertView);
			}
			//调用父类的方法把子View添加进来
			super.addView(newChild, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
		}
	}

	/** 重新分配区域 */
	public void redistribute() {
		resetAllAreas();//重新设置区域
		requestLayout();
	}

	/** 重新更新子View */
	public void refresh() {
		resetAllAreas();//重新分配区域
		generateChildren();//重新产生子View
		requestLayout();
	}

	/** 重写父类的removeAllViews */
	@Override
	public void removeAllViews() {
		super.removeAllViews();//先删除所有View
		resetAllAreas();//重新设置所有区域
	}

	/** 确定子View的位置,这个就是区域分布的关键 */
	@Override
	public void onLayout(boolean changed, int l, int t, int r, int b) {
		final int count = getChildCount();
		// 确定自身的宽高
		int thisW = r - l - this.getPaddingLeft() - this.getPaddingRight();
		int thisH = b - t - this.getPaddingTop() - this.getPaddingBottom();
		// 自身内容区域的右边和下边
		int contentRight = r - getPaddingRight();
		int contentBottom = b - getPaddingBottom();
		// 按照顺序存放把区域存放到集合中
		List<Integer> availAreas = new ArrayList<Integer>(mAreaCount);
		for (int i = 0; i < mAreaCount; i++) {
			availAreas.add(i);
		}

		int areaCapacity = (count + 1) / mAreaCount + 1;  //区域密度,表示一个区域内可以放几个View,+1表示至少要放一个
		int availAreaCount = mAreaCount; //可用的区域个数

		for (int i = 0; i < count; i++) {
			final View child = getChildAt(i);
			if (child.getVisibility() == View.GONE) { // gone掉的view是不参与布局
				continue;
			}

			if (!mFixedViews.contains(child)) {//mFixedViews用于存放已经确定好位置的View,存到了就没必要再次存放
				LayoutParams params = (LayoutParams) child.getLayoutParams();
				// 先测量子View的大小
				int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(this.getMeasuredWidth(), MeasureSpec.AT_MOST);//为子View准备测量的参数
				int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(this.getMeasuredHeight(), MeasureSpec.AT_MOST);
				child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
				// 子View测量之后的宽和高
				int childW = child.getMeasuredWidth();
				int childH = child.getMeasuredHeight();
				// 用自身的高度去除以分配值,可以算出每一个区域的宽和高
				float colW = thisW / (float) mXRegularity;
				float rowH = thisH / (float) mYRegularity;

				while (availAreaCount > 0) { //如果使用区域大于0,就可以为子View尝试分配
					int arrayIdx = mRdm.nextInt(availAreaCount);//随机一个list中的位置
					int areaIdx = availAreas.get(arrayIdx);//再根据list中的位置获取一个区域编号
					int col = areaIdx % mXRegularity;//计算出在二维数组中的位置
					int row = areaIdx / mXRegularity;
					if (mAreaDensity[row][col] < areaCapacity) {// 区域密度未超过限定,将view置入该区域
						int xOffset = (int) colW - childW; //区域宽度 和 子View的宽度差值,差值可以用来做区域内的位置随机
						if (xOffset <= 0) {
							xOffset = 1;
						}
						int yOffset = (int) rowH - childH;
						if (yOffset <= 0) {
							yOffset = 1;
						}
						// 确定左边,等于区域宽度*左边的区域
						params.mLeft = getPaddingLeft() + (int) (colW * col + mRdm.nextInt(xOffset));
						int rightEdge = contentRight - childW;
						if (params.mLeft > rightEdge) {//加上子View的宽度后不能超出右边界
							params.mLeft = rightEdge;
						}
						params.mRight = params.mLeft + childW;

						params.mTop = getPaddingTop() + (int) (rowH * row + mRdm.nextInt(yOffset));
						int bottomEdge = contentBottom - childH;
						if (params.mTop > bottomEdge) {//加上子View的宽度后不能超出右边界
							params.mTop = bottomEdge;
						}
						params.mBottom = params.mTop + childH;

						if (!isOverlap(params)) {//判断是否和别的View重叠了
							mAreaDensity[row][col]++;//没有重叠,把该区域的密度加1
							child.layout(params.mLeft, params.mTop, params.mRight, params.mBottom);//布局子View
							mFixedViews.add(child);//添加到已经布局的集合中
							break;
						} else {//如果重叠了,把该区域移除,
							availAreas.remove(arrayIdx);
							availAreaCount--;
						}
					} else {// 区域密度超过限定,将该区域从可选区域中移除
						availAreas.remove(arrayIdx);
						availAreaCount--;
					}
				}
			}
		}
		mLayouted = true;
	}

	/** 计算两个View是否重叠,如果重叠,那么他们之间一定有一个矩形区域是共有的 */
	private boolean isOverlap(LayoutParams params) {
		int l = params.mLeft - mOverlapAdd;
		int t = params.mTop - mOverlapAdd;
		int r = params.mRight + mOverlapAdd;
		int b = params.mBottom + mOverlapAdd;

		Rect rect = new Rect();

		for (View v : mFixedViews) {
			int vl = v.getLeft() - mOverlapAdd;
			int vt = v.getTop() - mOverlapAdd;
			int vr = v.getRight() + mOverlapAdd;
			int vb = v.getBottom() + mOverlapAdd;
			rect.left = Math.max(l, vl);
			rect.top = Math.max(t, vt);
			rect.right = Math.min(r, vr);
			rect.bottom = Math.min(b, vb);
			if (rect.right >= rect.left && rect.bottom >= rect.top) {
				return true;
			}
		}
		return false;
	}

	/** 内部类、接口 */
	public static interface Adapter {

		public abstract int getCount();

		public abstract View getView(int position, View convertView);
	}

	public static class LayoutParams extends ViewGroup.LayoutParams {

		private int mLeft;
		private int mRight;
		private int mTop;
		private int mBottom;

		public LayoutParams(ViewGroup.LayoutParams source) {
			super(source);
		}

		public LayoutParams(int w, int h) {
			super(w, h);
		}
	}
}
public class AnimationUtil {

	private static final long MEDIUM = 500;

	/** 创建一个淡入放大的动画 */
	public static Animation createZoomInNearAnim() {
		AnimationSet ret;
		Animation anim;
		ret = new AnimationSet(false);
		// 创建一个淡入的动画
		anim = new AlphaAnimation(0f, 1f);
		anim.setDuration(MEDIUM);
		anim.setInterpolator(new LinearInterpolator());
		ret.addAnimation(anim);
		// 创建一个放大的动画
		anim = new ScaleAnimation(0, 1, 0, 1, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
		anim.setDuration(MEDIUM);
		anim.setInterpolator(new DecelerateInterpolator());
		ret.addAnimation(anim);
		return ret;
	}

	/** 创建一个淡出放大的动画 */
	public static Animation createZoomInAwayAnim() {
		AnimationSet ret;
		Animation anim;
		ret = new AnimationSet(false);
		// 创建一个淡出的动画
		anim = new AlphaAnimation(1f, 0f);
		anim.setDuration(MEDIUM);
		anim.setInterpolator(new DecelerateInterpolator());
		ret.addAnimation(anim);
		// 创建一个放大的动画
		anim = new ScaleAnimation(1, 3, 1, 3, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
		anim.setDuration(MEDIUM);
		anim.setInterpolator(new DecelerateInterpolator());
		ret.addAnimation(anim);
		return ret;
	}

	/** 创建一个淡入缩小的动画 */
	public static Animation createZoomOutNearAnim() {
		AnimationSet ret;
		Animation anim;
		ret = new AnimationSet(false);
		// 创建一个淡入的动画
		anim = new AlphaAnimation(0f, 1f);
		anim.setDuration(MEDIUM);
		anim.setInterpolator(new LinearInterpolator());
		ret.addAnimation(anim);
		// 创建一个缩小的动画
		anim = new ScaleAnimation(3, 1, 3, 1, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
		anim.setDuration(MEDIUM);
		anim.setInterpolator(new DecelerateInterpolator());
		ret.addAnimation(anim);
		return ret;
	}

	/** 创建一个淡出缩小的动画 */
	public static Animation createZoomOutAwayAnim() {
		AnimationSet ret;
		Animation anim;
		ret = new AnimationSet(false);
		// 创建一个淡出的动画
		anim = new AlphaAnimation(1f, 0f);
		anim.setDuration(MEDIUM);
		anim.setInterpolator(new DecelerateInterpolator());
		ret.addAnimation(anim);
		// 创建一个缩小的动画
		anim = new ScaleAnimation(1, 0, 1, 0, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
		anim.setDuration(MEDIUM);
		anim.setInterpolator(new DecelerateInterpolator());
		ret.addAnimation(anim);
		return ret;
	}

	/** 创建一个淡入放大的动画 */
	public static Animation createPanInAnim(float degree) {
		AnimationSet ret;
		Animation anim;
		ret = new AnimationSet(false);
		// 创建一个淡入动画
		anim = new AlphaAnimation(0f, 1f);
		anim.setDuration(MEDIUM);
		anim.setInterpolator(new LinearInterpolator());
		ret.addAnimation(anim);
		// 创建一个放大动画
		final float pivotX = (float) (1 - Math.cos(degree)) / 2;
		final float pivotY = (float) (1 + Math.sin(degree)) / 2;

		anim = new ScaleAnimation(0.8f, 1, 0.8f, 1, Animation.RELATIVE_TO_SELF, pivotX, Animation.RELATIVE_TO_SELF,
				pivotY);
		anim.setDuration(MEDIUM);
		anim.setInterpolator(new DecelerateInterpolator());
		ret.addAnimation(anim);

		return ret;
	}

	/** 创建一个淡出缩小的动画 */
	public static Animation createPanOutAnim(float degree) {
		AnimationSet ret;
		Animation anim;
		ret = new AnimationSet(false);
		// 创建一个淡出动画
		anim = new AlphaAnimation(1f, 0f);
		anim.setDuration(MEDIUM);
		anim.setInterpolator(new DecelerateInterpolator());
		ret.addAnimation(anim);
		// 创建一个缩小动画
		final float pivotX = (float) (1 + Math.cos(degree)) / 2;
		final float pivotY = (float) (1 - Math.sin(degree)) / 2;
		anim = new ScaleAnimation(1, 0.8f, 1, 0.8f, Animation.RELATIVE_TO_SELF, pivotX, Animation.RELATIVE_TO_SELF,
				pivotY);
		anim.setDuration(MEDIUM);
		anim.setInterpolator(new DecelerateInterpolator());
		ret.addAnimation(anim);

		return ret;
	}
}

星空图控件

一个自定义控件,包含多个TextView元素。

每个TextView元素位置随机(x,y坐标)

通过上下可以切换分组的数据

使用步骤

一.获取分组数据

二.创建一个适配器

StellarMap.Adapter

getGroupCount();组数

getCount();指定group的元素个数

getView();元素视图

getNextGroupOnZoom();顺利

三.分布

setRegularity(25, 25);

包裹使用

 FrameLayout frameLayout = new FrameLayout(this);
    frameLayout.addView(stellarMap);//作为元素添加到布局
    frameLayout.setPadding(20, 20, 20, 20);
    setContentView(frameLayout);

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //setContentView(R.layout.activity_main);
    StellarMap stellarMap = new StellarMap(this);
    //设置背景
    stellarMap.setBackgroundColor(Color.YELLOW);
    final HashMap<Integer, List<String>> groups = getGroupData();
    //高级控件  ListView GridView(BaseAdapter)
    // ViewPager(pagerAdapter FragmentPagerAdapter)
    // PullToRefreshListView(BaseAdapter)
    // RecyclerView  (RecyclerView.Adapter)
    // TextView text.setText
    //适配器 :一堆get
    StellarMap.Adapter adapter = new StellarMap.Adapter() {
        //组内的元素个数
        @Override
        public int getCount(int group) {
            List<String> list = groups.get(group);
            return list.size();
        }
        //组数
        @Override
        public int getGroupCount() {
            return groups.size();
        }
        //获取指定group与指定下标的数据的展示元素
        @Override
        public View getView(int group, int position, View convertView) {
            TextView textView = new TextView(MainActivity.this);
            textView.setGravity(Gravity.CENTER);//居中
            textView.setTextColor(Color.GREEN);//绿色字体
            //获取一组指定下标的元素
            List<String> list = groups.get(group);
            String text = list.get(position);
            textView.setText(text);
            //缩进
            textView.setPadding(16, 16, 16, 16);
            //背景
            textView.setBackgroundColor(Color.GRAY);
            return textView;
        }

        //组的切换顺序
        @Override
        public int getNextGroupOnZoom(int group, boolean isZoomIn) {
            ++group;//下一组  3 组  0  1  2
            //3%3 --> 0
            //容易越界
            System.out.println("当前组" + group);
            return group % getGroupCount();
        }
    };
    stellarMap.setAdapter(adapter);
    //注意事项1.组的顺序 getNextGroupOnZoom 默认返回 0 总是显示第一组
    // 2.分布密度  横向最多15 ,竖直方向最多15
    stellarMap.setRegularity(25, 25);
    //3.添加padding
    FrameLayout frameLayout = new FrameLayout(this);
    frameLayout.addView(stellarMap);//作为元素添加到布局
    frameLayout.setPadding(20, 20, 20, 20);
    setContentView(frameLayout);
}

举报

相关推荐

0 条评论