@Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); mWidth = w; mHeight = h; //add by zhangxutong 2016 09 08 :解决源数据为空 或者size为0的情况, if (null == mIndexDatas || mIndexDatas.isEmpty()) { return; } computeGapHeight(); }
/** * 以下情况调用: * 1 在数据源改变 * 2 控件size改变时 * 计算gapHeight */ private void computeGapHeight() { mGapHeight = (mHeight - getPaddingTop() - getPaddingBottom()) / mIndexDatas.size(); }
public IndexBar(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(context, attrs, defStyleAttr); }
@Override public void onClick(View v) { ((SwipeMenuLayout) holder.itemView).quickClose(); mDatas.remove(holder.getAdapterPosition()); mIndexBar.setmPressedShowTextView(mTvSideBarHint)//设置HintTextView .setNeedRealIndex(true)//设置需要真实的索引 .setmLayoutManager(mManager)//设置RecyclerView的LayoutManager .setmSourceDatas(mDatas)//设置数据 .invalidate(); notifyDataSetChanged(); } });
/** * 更新数据源 * * @param view */ public void updateDatas(View view) { for (int i = 0; i < 5; i++) { mDatas.add(new CityBean("东京")); mDatas.add(new CityBean("大阪")); } mIndexBar.setmSourceDatas(mDatas) .invalidate(); mHeaderAdapter.notifyDataSetChanged(); } }
switch (event.getAction()) { case MotionEvent.ACTION_DOWN: setBackgroundColor(mPressedBackground);//手指按下时背景变色 int pressI = (int) ((y - getPaddingTop()) / mGapHeight); case MotionEvent.ACTION_CANCEL: default: setBackgroundResource(android.R.color.transparent);//手指抬起时背景恢复透明
@Override public void run() { mDatas = new ArrayList<>(); for (int i = 0; i < data.length; i++) { CityBean cityBean = new CityBean(); cityBean.setCity(data[i]);//设置城市名称 mDatas.add(cityBean); } mIndexBar.setmSourceDatas(mDatas)//设置数据 .setHeaderViewCount(mHeaderAdapter.getHeaderViewCount())//设置HeaderView数量 .invalidate(); mAdapter.setDatas(mDatas); mHeaderAdapter.notifyDataSetChanged(); mDecoration.setmDatas(mDatas); } }, 200);
@Override public void run() { mBodyDatas = new ArrayList<>(); for (int i = 0; i < data.length; i++) { MeiTuanBean cityBean = new MeiTuanBean(); cityBean.setCity(data[i]);//设置城市名称 mBodyDatas.add(cityBean); } //先排序 mIndexBar.getDataHelper().sortSourceDatas(mBodyDatas); mAdapter.setDatas(mBodyDatas); mHeaderAdapter.notifyDataSetChanged(); mSourceDatas.addAll(mBodyDatas); mIndexBar.setmSourceDatas(mSourceDatas)//设置数据 .invalidate(); mDecoration.setmDatas(mSourceDatas); } }, 1000);
private void init(Context context, AttributeSet attrs, int defStyleAttr) { int textSize = (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics());//默认的TextSize initIndexDatas(); setmOnIndexPressedListener(new onIndexPressedListener() { @Override public void onIndexPressed(int index, String text) {
/** * 更新数据源 * * @param view */ public void updateDatas(View view) { for (int i = 0; i < 5; i++) { mBodyDatas.add(new MeiTuanBean("东京")); mBodyDatas.add(new MeiTuanBean("大阪")); } //先排序 mIndexBar.getDataHelper().sortSourceDatas(mBodyDatas); mSourceDatas.clear(); mSourceDatas.addAll(mHeaderDatas); mSourceDatas.addAll(mBodyDatas); mHeaderAdapter.notifyDataSetChanged(); mIndexBar.invalidate(); } }
/** * 一定要在设置数据源{@link #setmSourceDatas(List)}之前调用 * * @param needRealIndex * @return */ public IndexBar setNeedRealIndex(boolean needRealIndex) { isNeedRealIndex = needRealIndex; initIndexDatas(); return this; }
public IndexBar setmSourceDatas(List<? extends BaseIndexPinyinBean> mSourceDatas) { this.mSourceDatas = mSourceDatas; initSourceDatas();//对数据源进行初始化 return this; }
@Override protected void onDraw(Canvas canvas) { int t = getPaddingTop();//top的基准点(支持padding) String index;//每个要绘制的index内容 for (int i = 0; i < mIndexDatas.size(); i++) { index = mIndexDatas.get(i); Paint.FontMetrics fontMetrics = mPaint.getFontMetrics();//获得画笔的FontMetrics,用来计算baseLine。因为drawText的y坐标,代表的是绘制的文字的baseLine的位置 int baseline = (int) ((mGapHeight - fontMetrics.bottom - fontMetrics.top) / 2);//计算出在每格index区域,竖直居中的baseLine值 canvas.drawText(index, mWidth / 2 - mPaint.measureText(index) / 2, t + mGapHeight * i + baseline, mPaint);//调用drawText,居中显示绘制index } }
/** * 根据传入的pos返回tag * * @param tag * @return */ private int getPosByTag(String tag) { //add by zhangxutong 2016 09 08 :解决源数据为空 或者size为0的情况, if (null == mSourceDatas || mSourceDatas.isEmpty()) { return -1; } if (TextUtils.isEmpty(tag)) { return -1; } for (int i = 0; i < mSourceDatas.size(); i++) { if (tag.equals(mSourceDatas.get(i).getBaseIndexTag())) { return i + getHeaderViewCount(); } } return -1; }
@Override public void run() { mDatas = new ArrayList<>(); //微信的头部 也是可以右侧IndexBar导航索引的, // 但是它不需要被ItemDecoration设一个标题titile mDatas.add((CityBean) new CityBean("新的朋友").setTop(true).setBaseIndexTag(INDEX_STRING_TOP)); mDatas.add((CityBean) new CityBean("群聊").setTop(true).setBaseIndexTag(INDEX_STRING_TOP)); mDatas.add((CityBean) new CityBean("标签").setTop(true).setBaseIndexTag(INDEX_STRING_TOP)); mDatas.add((CityBean) new CityBean("公众号").setTop(true).setBaseIndexTag(INDEX_STRING_TOP)); for (int i = 0; i < data.length; i++) { CityBean cityBean = new CityBean(); cityBean.setCity(data[i]);//设置城市名称 mDatas.add(cityBean); } mAdapter.setDatas(mDatas); mAdapter.notifyDataSetChanged(); mIndexBar.setmPressedShowTextView(mTvSideBarHint)//设置HintTextView .setNeedRealIndex(true)//设置需要真实的索引 .setmLayoutManager(mManager)//设置RecyclerView的LayoutManager .setmSourceDatas(mDatas)//设置数据 .invalidate(); mDecoration.setmDatas(mDatas); } }, 2000);
/** * 更新数据源 * * @param view */ public void updateDatas(View view) { for (int i = 0; i < 5; i++) { mDatas.add(new CityBean("东京")); mDatas.add(new CityBean("大阪")); } mIndexBar.setmSourceDatas(mDatas) .invalidate(); mAdapter.notifyDataSetChanged(); }
/** * 更新数据源 * * @param view */ public void updateDatas(View view) { for (int i = 0; i < 5; i++) { mDatas.add(new CityBean("东京")); mDatas.add(new CityBean("大阪")); } mIndexBar.setmSourceDatas(mDatas) .invalidate(); mAdapter.notifyDataSetChanged(); } }
/** * 初始化原始数据源,并取出索引数据源 * * @return */ private void initSourceDatas() { //add by zhangxutong 2016 09 08 :解决源数据为空 或者size为0的情况, if (null == mSourceDatas || mSourceDatas.isEmpty()) { return; } if (!isSourceDatasAlreadySorted) { //排序sourceDatas mDataHelper.sortSourceDatas(mSourceDatas); } else { //汉语->拼音 mDataHelper.convert(mSourceDatas); //拼音->tag mDataHelper.fillInexTag(mSourceDatas); } if (isNeedRealIndex) { mDataHelper.getSortedIndexDatas(mSourceDatas, mIndexDatas); computeGapHeight(); } //sortData(); }
@Override public void run() { mDatas = new ArrayList<>(); //微信的头部 也是可以右侧IndexBar导航索引的, // 但是它不需要被ItemDecoration设一个标题titile mDatas.add((CityBean) new CityBean("新的朋友").setTop(true).setBaseIndexTag(INDEX_STRING_TOP)); mDatas.add((CityBean) new CityBean("群聊").setTop(true).setBaseIndexTag(INDEX_STRING_TOP)); mDatas.add((CityBean) new CityBean("标签").setTop(true).setBaseIndexTag(INDEX_STRING_TOP)); mDatas.add((CityBean) new CityBean("公众号").setTop(true).setBaseIndexTag(INDEX_STRING_TOP)); for (int i = 0; i < data.length; i++) { CityBean cityBean = new CityBean(); cityBean.setCity(data[i]);//设置城市名称 mDatas.add(cityBean); } mAdapter.setDatas(mDatas); mAdapter.notifyDataSetChanged(); mIndexBar.setmSourceDatas(mDatas)//设置数据 .invalidate(); mDecoration.setmDatas(mDatas); } }, 500);