Androidstudio自定义控件,快速索引联系人的首字母条,效果图及代码详解
2016-11-22 14:28
585 查看
效果图:实际开发中除了部分服务性的需要使用模拟器调试外,我们基本都使用真机调试,体验效果更好,便于测试自定义代码开发顺序一般是先mainActivi 再创建自定义View类,写UI,再开发,各位同僚也是比较清楚了,我就不献丑了,代码我就先放UI了
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.jms0313.quickindex.MainActivity"> <ListView android:id="@+id/lv_view" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <com.jms0313.quickindex.QuickView.QuickView android:id="@+id/quick_bar" android:layout_width="30dp" android:layout_height="match_parent" android:layout_alignParentRight="true" android:background="#ff0000"> </com.jms0313.quickindex.QuickView.QuickView> <TextView android:visibility="gone" android:id="@+id/tv_show" android:layout_width="80dp" android:layout_height="80dp" android:text="A" android:gravity="center" android:layout_centerInParent="true" android:textColor="#ffffff" android:textSize="50sp" android:background="@drawable/tv_circle"/> </RelativeLayout>adapter_list.xml<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:id="@+id/tv_first" android:padding="8dp" android:gravity="center_vertical" android:layout_width="match_parent" android:layout_height="60dp" android:text="A" android:textColor="#fff" android:textSize="30sp" android:background="#66000000"/> <TextView android:id="@+id/tv_name" android:gravity="center_vertical" android:padding="8dp" android:layout_width="match_parent" android:layout_height="60dp" android:textColor="#000000" android:textSize="30sp" android:text="乔峰" /> </LinearLayout>主界面代码详解 MainActivitypackage com.jms0313.quickindex; import android.os.Bundle; import android.os.Handler; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.ListView; import android.widget.TextView; import com.jms0313.quickindex.QuickView.Bean.Friend; import com.jms0313.quickindex.QuickView.QuickView; import java.util.ArrayList; import java.util.Collections; public class MainActivity extends AppCompatActivity { private ListView lv_view; private QuickView quick_bar; private TextView tv_show; private Handler handler=new Handler(); private ArrayList<Friend> friends=new ArrayList<Friend>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); /**初始化控件*/ init(); /**初始化数据*/ prepareData(); Collections.sort(friends); lv_view.setAdapter(new MyAdapter(friends)); /**数据监听事件*/ quick_bar.setOnTextChangeListener(new QuickView.OnTextChangeListener() { @Override public void textChange(String text) { for (int i = 0; i < friends.size(); ++i) { String firstChar= friends.get(i).pinyin.charAt(0)+""; if(firstChar.equalsIgnoreCase(text)){ lv_view.setSelection(i); break; } } showText(text); } }); } private void showText(String text) { handler.removeCallbacksAndMessages(null); tv_show.setText(text); tv_show.setVisibility(View.VISIBLE); handler.postDelayed(new Runnable() { @Override public void run() { tv_show.setVisibility(View.GONE); } },2000); } private void init() { lv_view = (ListView) findViewById(R.id.lv_view); quick_bar = (QuickView) findViewById(R.id.quick_bar); tv_show = (TextView) findViewById(R.id.tv_show); } /** * 准备数据 */ private void prepareData() { // 虚拟数据 friends.add(new Friend("李伟")); friends.add(new Friend("张三")); friends.add(new Friend("阿三")); friends.add(new Friend("阿四")); friends.add(new Friend("段誉")); friends.add(new Friend("段正淳")); friends.add(new Friend("张三丰")); friends.add(new Friend("陈坤")); friends.add(new Friend("林俊杰1")); friends.add(new Friend("陈坤2")); friends.add(new Friend("王二a")); friends.add(new Friend("林俊杰a")); friends.add(new Friend("张四")); friends.add(new Friend("林俊杰")); friends.add(new Friend("王二")); friends.add(new Friend("王二b")); friends.add(new Friend("赵四")); friends.add(new Friend("杨坤")); friends.add(new Friend("赵子龙")); friends.add(new Friend("杨坤1")); friends.add(new Friend("李伟1")); friends.add(new Friend("宋江")); friends.add(new Friend("宋江1")); friends.add(new Friend("李伟3")); } }自定义控件QuickView 代码详解package com.jms0313.quickindex.QuickView; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.view.View; import com.jms0313.quickindex.R; /** * Created by liying on 2016/11/20. */ public c356 class QuickView extends View { private static final String TAG = "QuickView"; private String[] indexArr = {"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 paint; private float cellHeight; private int currentIndex; private OnTextChangeListener mOnTextChangeListener; public QuickView(Context context) { this(context, null); } public QuickView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public QuickView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init() { paint = new Paint(Paint.ANTI_ALIAS_FLAG); paint.setColor(Color.WHITE); /**通过dimens设置文字的规格*/ paint.setTextSize(getResources().getDimensionPixelSize(R.dimen.textSize)); paint.setTextAlign(Paint.Align.CENTER); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); cellHeight = getMeasuredHeight() * 1f / indexArr.length; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); for (int i = 0; i < indexArr.length; ++i) { float x = getMeasuredWidth() / 2; float y = cellHeight / 2 + cellHeight * i + getTextHeight(indexArr[i]) / 2; paint.setColor(i==currentIndex?Color.BLACK:Color.WHITE); canvas.drawText(indexArr[i], x, y, paint); } } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: break; case MotionEvent.ACTION_MOVE: int index= (int) (event.getY()/cellHeight); if(currentIndex!=index){ if(index>=0&&index<indexArr.length){ Log.i(TAG, "onTouchEvent: "+indexArr[index]); if(mOnTextChangeListener!=null){ mOnTextChangeListener.textChange(indexArr[index]); } } currentIndex=index; } break; case MotionEvent.ACTION_UP: currentIndex = -1; break; } invalidate(); return true; } private float getTextHeight(String s) { /** * start end 表示的是文字的起始位置,如果文字有一大串,表示从第start个到end个 * bounds 文字的举行边框 */ Rect bounds = new Rect(); paint.getTextBounds(s, 0, s.length(), bounds); return bounds.height(); } public void setOnTextChangeListener(OnTextChangeListener mOnTextChangeListener) { this.mOnTextChangeListener = mOnTextChangeListener; } public interface OnTextChangeListener { void textChange(String text); } }业务bean代码friend详解package com.jms0313.quickindex.QuickView.Bean; import com.jms0313.quickindex.utils.PinYin; /** * Created by liying on 2016/11/20. */ public class Friend implements Comparable<Friend> { private String name; public String pinyin; public String getName() { return name; } public void setName(String name) { this.name = name; } public Friend(String name) { this.name = name; this.pinyin= PinYin.getPinYin(name); } @Override public int compareTo(Friend o) { return pinyin.compareTo(o.pinyin); } }pinyin工具类代码详解package com.jms0313.quickindex.utils; import android.text.TextUtils; import net.sourceforge.pinyin4j.PinyinHelper; import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType; import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat; import net.sourceforge.pinyin4j.format.HanyuPinyinToneType; import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination; /** * Created by liying on 2016/11/20. */ public class PinYin { public static String getPinYin(String name) { if (TextUtils.isEmpty(name)) { return null;} HanyuPinyinOutputFormat format=new HanyuPinyinOutputFormat(); /**大写字母*/ format.setCaseType(HanyuPinyinCaseType.UPPERCASE); /**不带发音*/ format.setToneType(HanyuPinyinToneType.WITHOUT_TONE); StringBuilder sb=new StringBuilder( ); final char[] chars = name.toCharArray(); for(char ch:chars){ /**过滤空格,如果是空格,跳转下一个*/ if(Character.isWhitespace(ch)){ continue; } if(ch>127){ try { final String[] strings = PinyinHelper.toHanyuPinyinStringArray(ch, format); if(strings!=null&&strings.length>0){ /**由于有多音字的存在,目前只能取得第一个*/ sb.append(strings[0]); } } catch (BadHanyuPinyinOutputFormatCombination badHanyuPinyinOutputFormatCombination) { badHanyuPinyinOutputFormatCombination.printStackTrace(); } }else{ sb.append(ch); } } return sb.toString(); } }数据填充 MyAdapter代码package com.jms0313.quickindex; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.TextView; import com.jms0313.quickindex.QuickView.Bean.Friend; import java.util.ArrayList; /** * Created by liying on 2016/11/20. */ public class MyAdapter extends BaseAdapter { private ArrayList<Friend> friends; public MyAdapter(ArrayList<Friend> friends) { this.friends = friends; } @Override public int getCount() { return friends.size(); } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; if (convertView == null) { convertView = View.inflate(parent.getContext(), R.layout.adapter_list, null); holder = new ViewHolder(); holder.tv_first = (TextView) convertView.findViewById(R.id.tv_first); holder.tv_name = (TextView) convertView.findViewById(R.id.tv_name); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } String firstChar = friends.get(position).pinyin.charAt(0) + ""; if (position > 0) { String lastChar = friends.get(position - 1).pinyin.charAt(0) + ""; if (firstChar.equalsIgnoreCase(lastChar)) { holder.tv_first.setVisibility(View.GONE); } else { holder.tv_first.setVisibility(View.VISIBLE); holder.tv_first.setText(firstChar); } } else { holder.tv_first.setVisibility(View.VISIBLE); holder.tv_first.setText(firstChar); } holder.tv_name.setText(friends.get(position).getName()); return convertView; } @Override public Object getItem(int position) { return null; } @Override public long getItemId(int position) { return 0; } static class ViewHolder { private TextView tv_first; private TextView tv_name; } }适配器中可以使用butterKnife自动生成ViewHolder备注:编写过程中注释写的比较少,如果有不清楚的地方可以给我留言!static class ViewHolder {@Bind(R.id.letter)TextView letter;@Bind(R.id.name)TextView name;ViewHolder(View view) {ButterKnife.bind(this, view);view.setTag(this);}
相关文章推荐
- android 仿微信联系人 首字母分组快速索引
- [Android开发] 在项目中快速实现 列表字母排序滑动索引 功能原理以及过程代码
- Android开发之仿联系人界面(根据文字首字母A、B、C实现快速索引)
- Android手机联系人带字母索引的快速查找
- 字母全排列快速算法C代码
- 联系人字母快速搜索
- 联系人字母索引实现
- Android 联系人分章节显示以及ListView快速滑动显示联系人首字母
- 字母全排列快速算法C代码
- Android 快速索引(城市列表和联系人)
- Android学习笔记(三)之带有侧边索引的快速查找(跟带字母索引查找的通讯录差不多)
- 详解 Eclipse 中的快速 Java 编码(代码模板)
- 详解--快速排序---附加java代码
- 详解 Eclipse 中的快速 Java 编码(代码模板)
- 仿联系人列表或其他上的字母索引
- 字母全排列快速算法C代码
- ListView字母快速索引 自动搜索
- 字母全排列快速算法C代码
- 自定义类似微信联系人列表姓名首字母边栏索引列表效果
- 快速生成折线图及代码详解