ListView A~Z快速索引--提供源码
来源:互联网 发布:json在线美化 编辑:程序博客网 时间:2024/06/15 11:51
ListView A~Z快速索引这种效果在通信录和城市列表中经常看到,方便用户查找,是一种增加用户体验的好方法。
效果图如下:
使用的知识点:
1,汉字转拼音,使用pinyin4j-2.5.0.jar
2,定义类实现Comparable接口,方便排序
3,自定义控件QuickIndexBar继承view(重点)
4,使用接口回调,暴露给外部使用
实现步骤:
1,设置布局
2,使用pinyin4j-2.5.0.jar库,定义把汉字转化为拼音的方法,3,把listview中的数据转化成拼音,并对其进行排序,进行绑定
4,自定义a-z控件,设置触摸touch事件,暴露接口,提供回调
5,根据按下索引位置的字母,listview跳转到对应的位置,同时按下位置的字母颜色变灰,同时在中间提示字母
下面就来看代码:
1,activity_main.xml
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <ListView android:id="@+id/lv_data" android:layout_width="match_parent" android:layout_height="match_parent"> </ListView> <com.hdc.listviewquickindex.QuickIndexBar android:id="@+id/quickIndexBar" android:layout_width="40dp" android:layout_height="match_parent" android:background="#ff0000" android:layout_alignParentRight="true" /> <TextView android:id="@+id/tv_tip" android:layout_width="50dp" android:layout_height="50dp" android:textSize="40sp" android:textColor="@android:color/white" android:background="@drawable/tip_bg_shape" android:layout_centerInParent="true" android:gravity="center" android:visibility="gone" android:text="A"/></RelativeLayout>2,数据实体类GoodMan.java
package com.hdc.listviewquickindex;import com.hdc.listviewquickindex.utils.PinyinUtil;import java.util.Comparator;/** * 实现Comparable接口,使GoodMan具有可比性 * Created by wk on 2016/6/14. */public class GoodMan implements Comparable<GoodMan>{ public String name; public String pinyin; public GoodMan(String name) { this.name = name; this.pinyin = PinyinUtil.getPinyin(name); } @Override public int compareTo(GoodMan another) { return this.pinyin.compareTo(another.pinyin); }}3,listview适配器MyAdapter.java
package com.hdc.listviewquickindex;import android.content.Context;import android.text.TextUtils;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.TextView;import java.util.List;/** * Created by wk on 2016/6/14. */public class MyAdapter extends BaseAdapter { private Context mContext; private List<GoodMan> datas; public MyAdapter(Context context, List<GoodMan> datas){ this.mContext = context; this.datas = datas; } @Override public int getCount() { if(datas!=null){ return datas.size(); } return 0; } @Override public GoodMan getItem(int position) { return datas.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder = null; if(convertView == null){ holder = new ViewHolder(); convertView = View.inflate(mContext,R.layout.item_man,null); holder.tv_index = (TextView) convertView.findViewById(R.id.tv_index); holder.tv_name = (TextView) convertView.findViewById(R.id.tv_name); convertView.setTag(holder); }else{ holder = (ViewHolder) convertView.getTag(); } //判断当前条目的拼音的首字母和上一条目的首字母是否相同 //如果相同则不显示,不同则显示索引 String firstLetter = datas.get(position).pinyin.charAt(0)+""; if(position == 0){ holder.tv_index.setVisibility(View.VISIBLE); holder.tv_index.setText(firstLetter); }else{ String preLetter = datas.get(position-1).pinyin.charAt(0)+""; if(TextUtils.equals(firstLetter,preLetter)){ holder.tv_index.setVisibility(View.GONE); holder.tv_index.setText(firstLetter); }else{ holder.tv_index.setVisibility(View.VISIBLE); holder.tv_index.setText(firstLetter); } } holder.tv_name.setText(datas.get(position).name); return convertView; } public class ViewHolder{ private TextView tv_index; private TextView tv_name; }}4,主界面MainActivity.java
package com.hdc.listviewquickindex;import android.os.Handler;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.text.TextUtils;import android.view.View;import android.view.Window;import android.widget.ListView;import android.widget.TextView;import java.util.ArrayList;import java.util.Collections;import java.util.List;public class MainActivity extends AppCompatActivity { private List<GoodMan> mDatas; private ListView mLv_data; private TextView mTv_tip; private MyAdapter mMyAdapter; private QuickIndexBar mQuickIndexBar; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_main); mLv_data = (ListView) findViewById(R.id.lv_data); mTv_tip = (TextView)findViewById(R.id.tv_tip); mQuickIndexBar = (QuickIndexBar) findViewById(R.id.quickIndexBar); initData(); mMyAdapter = new MyAdapter(this,mDatas); mLv_data.setAdapter(mMyAdapter); mQuickIndexBar.setOnLetterChangeListener(new QuickIndexBar.OnLetterChangeListener() { @Override public void onLetterChange(String letter) { showLetter(letter); for (int i = 0;i<mDatas.size();i++){ if(TextUtils.equals(letter,mDatas.get(i).pinyin.charAt(0)+"")){ mLv_data.setSelection(i); break; } } } }); } private void initData() { mDatas = new ArrayList<GoodMan>(); for(int i = 0;i< Cheeses.NAMES.length;i++){ GoodMan goodMan = new GoodMan(Cheeses.NAMES[i]); mDatas.add(goodMan); } //对list中的数据进行排序 Collections.sort(mDatas); } Handler mHandler = new Handler(); /** * 显示字母提示 * @param letter */ public void showLetter(String letter){ mTv_tip.setVisibility(View.VISIBLE); mTv_tip.setText(letter); //取消掉刚刚所有的演示操作 mHandler.removeCallbacksAndMessages(null); mHandler.postDelayed(new Runnable() { @Override public void run() { mTv_tip.setVisibility(View.GONE); } },1000); }}5,自定义控件QuickIndexBar.java
package com.hdc.listviewquickindex;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Rect;import android.graphics.Typeface;import android.support.v4.view.MotionEventCompat;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import com.hdc.listviewquickindex.utils.Utils;/** * Created by wk on 2016/6/14. */public class QuickIndexBar extends View { private static final String[] LETTERS = new String[]{ "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"}; private Paint mPaint; private int mCellWidth; private int mHeight; private float mCellHeight; private OnLetterChangeListener mOnLetterChangeListener; public interface OnLetterChangeListener{ void onLetterChange(String letter); } public void setOnLetterChangeListener(OnLetterChangeListener listener){ this.mOnLetterChangeListener = listener; } /** * 控件在java中使用时调用一个参数的构造方法 * @param context */ public QuickIndexBar(Context context) { this(context,null); } /** * 控件在xml文件中使用时调用两个参数的构造方法 * @param context * @param attrs */ public QuickIndexBar(Context context, AttributeSet attrs) { this(context, attrs,0); } public QuickIndexBar(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(context); } public void init(Context context){ mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); int pxValue = Utils.dip2px(context,16f); //画笔大小 mPaint.setTextSize(pxValue); //画笔颜色 mPaint.setColor(Color.WHITE); //加粗 mPaint.setTypeface(Typeface.DEFAULT_BOLD); } //onSizeChanged 先于onDraw 方法执行 @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); //获取单元格高度 mCellWidth = getMeasuredWidth(); //获取高度 mHeight = getMeasuredHeight(); //获取单元格的高度 mCellHeight = mHeight *1f/LETTERS.length; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //把字母画出来 for (int i=0;i<LETTERS.length;i++){ String text = LETTERS[i]+""; //获取字母的宽度 float letterWidth = mPaint.measureText(text); float x = mCellWidth*0.5f - letterWidth*0.5f; //获取字母的高度 Rect bounds = new Rect(); mPaint.getTextBounds(text, 0, text.length(), bounds); float letterHeight = bounds.height(); float y = mCellHeight*0.5f + letterHeight * 0.5f + mCellHeight * i; //如果当前绘制的字母和按压的索引一样则用灰色的画笔 mPaint.setColor((index==i)?Color.GRAY:Color.WHITE); // x默认是这个字符串的左边在屏幕的位置 // y是指定这个字符baseline在屏幕上的位置 canvas.drawText(text,x,y,mPaint); } } int index = -1; @Override public boolean onTouchEvent(MotionEvent event) { float y = -1; int currentIndex = -1; switch (MotionEventCompat.getActionMasked(event)){ case MotionEvent.ACTION_DOWN: y = event.getY(); currentIndex = (int)(y/mCellHeight); // 健壮性处理, 在正常范围内 if(currentIndex>= 0&& currentIndex<LETTERS.length){ // 字母的索引发生了变化 if(index != currentIndex){ if(mOnLetterChangeListener != null){ String letter = LETTERS[currentIndex]+""; mOnLetterChangeListener.onLetterChange(letter); } index = currentIndex; } } break; case MotionEvent.ACTION_MOVE: y = event.getY(); currentIndex = (int)(y/mCellHeight); // 健壮性处理, 在正常范围内 if(currentIndex>= 0&& currentIndex<LETTERS.length){ // 字母的索引发生了变化 if(index != currentIndex){ if(mOnLetterChangeListener != null){ String letter = LETTERS[currentIndex]+""; mOnLetterChangeListener.onLetterChange(letter); } index = currentIndex; } } break; case MotionEvent.ACTION_UP: index = -1; break; default: break; } //使生效,重新调用onDraw方法 invalidate(); //返回true表示消费touch事件 return true; }}
以上是主要代码实现,相信注释已经非常详细了,还有些就没有贴出来了
如果需要源码,请点击这里,欢迎留言。。。
1 0
- ListView A~Z快速索引--提供源码
- 实现ListView A~Z快速索引
- Android ListView A~Z快速索引
- 实现ListView A~Z快速索引
- Android ListView A~Z快速索引(改进版)
- 快速集成android实现listview的字母A-Z排序,界面侧边字母索引
- 快速集成android实现listview的字母A-Z排序,界面侧边字母索引
- listview按字母A-Z快速定位
- Android之联系人A~Z快速索引效果
- ListView 实现点击侧边A-Z快速查找
- ListView 实现点击侧边A-Z快速查找
- ListView 实现点击侧边A-Z快速查找
- js a-z索引排序
- Android ListView城市列表,按a-z分组字母索引排序
- ListView的快速索引
- 融合了A~Z快速索引和侧滑菜单的ListVeiw的demo
- ListView 实现点击侧边A-Z快速查找[中英文排序混排]
- android listview实现快速查询A—Z (模拟一些天气搜狐,网易等天气预报)
- 【LeetCode】260. Single Number III
- SpringMVC返回Json的做法
- 计算机视觉/模式识别/图像会议
- C语言基本类型
- iOS开发--触摸事件、手势识别、摇晃事件、耳机线控
- ListView A~Z快速索引--提供源码
- 在web.xml中配置SpringMVC的启动配置项
- const char*, char const*, char*const区分方法
- 将 int a 第三位清零、置1、去反
- 基于ARM 构架(带MMU)的copy_from_user与copy_to_user详细分析
- 实现二级域名
- STM32之中断
- Oracle:导入导出
- apache反向代理