栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Android自定义滚动条——城市列表

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Android自定义滚动条——城市列表

Android自定义滚动条——城市列表

效果视频

绘制滚动条

区别选中与未选择文字绘制等高间距滑动事件监听 解析承载城市数据的XML文件

下载XML文件解析文件 适配器

建立适配器类适配器子项视图

效果图代码 适配器绑定 单向绑定

效果视频 绘制滚动条 区别选中与未选择文字
private void init() {
        mLetterList = Arrays.asList(INDEX_STRING);
        mTextNormalColor = Color.parseColor("#000000");
        mTextSelectedColor = Color.parseColor("#ff0000");
    }
绘制等高间距

将一个布局高度绘制成26等份,对应26个字母

 protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int height = getHeight();
        int width = getWidth();
        int singleHeight = height / mLetterList.size(); // 获取每一个字母的高度
        for (int i = 0; i < mLetterList.size(); i++) {
            mPaint.setColor(mTextNormalColor);
            mPaint.setTypeface(Typeface.DEFAULT);
            mPaint.setAntiAlias(true);
            mPaint.setTextSize(32);
            // 选中的状态
            if (i == mChoose) {
                mPaint.setColor(mTextSelectedColor);
                mPaint.setFakeBoldText(true);
            }
            // x 坐标等于中间-字符串宽度的一半
            float xPos = width / 2.0f - mPaint.measureText(mLetterList.get(i)) / 2;
            float yPos = singleHeight * i + singleHeight / 2.0f;
            canvas.drawText(mLetterList.get(i), xPos, yPos, mPaint);
            mPaint.reset(); // 重置画笔
        }
滑动事件监听
 public boolean onTouchEvent(MotionEvent event) {
        final int action = event.getAction();
        final float y = event.getY(); // 点击 y 坐标
        // 点击 y 坐标所占总高度的比例*b数组的长度就等于点击 b 中的个数
        final int c = (int) (y / getHeight() * mLetterList.size());

        switch (action) {
            case MotionEvent.ACTION_UP:
                if (monTextPositionChangedListener != null) {
                    mOnTextPositionChangedListener.onActionUp();
                }
                mChoose = -1;
                invalidate();
                break;
            default:
                if (mChoose != c) {
                    if (c >= 0 && c < mLetterList.size()) {
                        if (monTouchLetterChangedListener != null) {
                            mOnTouchLetterChangedListener.onTouchingLetterChanged(mLetterList.get(c));
                        }
                        mChoose = c;
                        invalidate();
                    }
                }
                if (monTextPositionChangedListener != null && y >= 0 && y <= getHeight()) {
                    mOnTextPositionChangedListener.onTextPositionChanged(mLetterList.get(mChoose), (int) y);
                }
                break;
        }
        return true;
    }
解析承载城市数据的XML文件 下载XML文件

从网上下载一个包含全部城市、城市代码、城市拼音首字母的文件,可以是xml格式亦或json格式
文件下载链接

解析文件

从xml文件中取出城市数据,按城市名称、城市代码、城市首字母三个信息为一组,实例化实体类对象,并保存到列表中

private void InitCityInfo(){
        AllCityList = new ArrayList<>(  );
        String[] cityArray = getResources().getStringArray(R.array.city);
        // 侧边栏的索引字母
        ArrayList indexList = new ArrayList<>();
        String curGroup = "0";
        for (int i = 0; i < cityArray.length; i += 3) {
            CityInfo cityInfo = new CityInfo(cityArray[i], cityArray[i + 1], cityArray[i + 2],
                    false, false);
            if (!cityInfo.getGroup().equals(curGroup)) {
                // 如果当前城市的 group 信息与保存的不一致, 那么就是该 group 的第一个
                cityInfo.setIsFirstInGroup(true);
                // 同时将该 group 信息添加到索引中
                indexList.add(cityInfo.getGroup());
                // 它的上一个城市就是上一个 group 的最后一个
                if (i > 0) {
                    AllCityList.get(AllCityList.size() - 1).setIsLastInGroup(true);
                }
                curGroup = cityInfo.getGroup();
            }
            AllCityList.add(cityInfo);
        }
        //AllCitiesScrollBar.setIndexText(indexList);
    }
适配器 建立适配器类

将解析出的城市数据,添加到RecyclerView子项中

public class AllCitiesReclcyerView extends RecyclerView.Adapter {
    private List mCityInfo;

    public AllCitiesReclcyerView(List mCityInfo){
      this.mCityInfo = mCityInfo;
    }
    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from( parent.getContext() ).inflate( R.layout.allcities_recyclerview_item,null,false );
        return new ViewHolder( view );
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
       CityInfo cityInfo = mCityInfo.get( position );
        holder.CityName.setText( cityInfo.getCityName());
    }

    @Override
    public int getItemCount() {
        return mCityInfo.size();
    }
    public int getPositionForSection(char section) {
        for (int i = 0; i < getItemCount(); i++) {
            String group = mCityInfo.get(i).getGroup();
            char firstChar = group.charAt(0);
            if (firstChar == section) {
                return i;
            }
        }
        return -1;
    }
    class ViewHolder extends RecyclerView.ViewHolder{
        private TextView CityName;

        public ViewHolder(@NonNull View itemView) {
            super( itemView );
            CityName = itemView.findViewById( R.id.CityName );
        }
    }
}
适配器子项视图 效果图 代码



    

    

适配器绑定
 View AllCities = LayoutInflater.from( City.this).inflate( R.layout.choosecity_recyclerview1,null);
        AllCities_RecyclerView = AllCities.findViewById( R.id.AllCities );
        AllCitiesScrollBar = AllCities.findViewById( R.id.AllCitiesScrollBar );
        CityTipsText = AllCities.findViewById( R.id.CityTipsText );
        LinearLayoutManager manager1 = new LinearLayoutManager( City.this );
        AllCities_RecyclerView.setLayoutManager( manager1 );
        AllCitiesReclcyerView allCitiesReclcyerView = new AllCitiesReclcyerView( AllCityList );
        AllCities_RecyclerView.setAdapter( allCitiesReclcyerView );
        //分割线

此语句作用为:为每一个子项之间添加一个分割线

  AllCities_RecyclerView.addItemDecoration(new CityItemDecoration(AllCityList));
单向绑定

通过滑动滚动条,相应的改变RecyclerView子项位置;并对滑到的滚动条字母进行突出显示

AllCities_RecyclerView.addItemDecoration(new CityItemDecoration(AllCityList));
        AllCitiesScrollBar.setonTouchLetterChangedListener( new SideBar.onTouchingLetterChangedListener() {
            @Override
            public void onTouchingLetterChanged(String s) {
                int position = allCitiesReclcyerView.getPositionForSection(s.charAt(0));
                if (position != -1) {
                    manager1.scrollToPositionWithOffset(position, 0);
                }
            }
        } );
        AllCitiesScrollBar.setonTextPositionChangedListener( new SideBar.onTextPositionChangedListener() {
            @Override
            public void onTextPositionChanged(String c, int y) {
                CityTipsText.setVisibility(View.VISIBLE);
                int sideBarY = AllCitiesScrollBar.getTop();
                int topMargin = sideBarY + y - CityTipsText.getHeight() / 2;
                RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) CityTipsText.getLayoutParams();
                lp.topMargin = topMargin;
                CityTipsText.setLayoutParams(lp);
                CityTipsText.setText(c);
            }

            @Override
            public void onActionUp() {
                CityTipsText.setVisibility(View.INVISIBLE);
            }
        } );
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/753896.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号