您的位置:首页 > 移动开发 > Android开发

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>
主界面代码详解 MainActivity
package 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);}
备注:编写过程中注释写的比较少,如果有不清楚的地方可以给我留言!

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息