先从自定义控件代码来看吧
t.Context;
aphics.Canvas;
aphics.Color;
aphics.Paint;
aphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast;/*** 自定义View 快速索引* @author 李帅帅* */
public class QuickIndexView extends View {public QuickIndexView(Context context, AttributeSet attrs) {super(context, attrs);paint = new Paint();paint.setAntiAlias(true);}private float itemWidth;// item的宽度private float itemHight;// item的高度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;/*** 测量*/@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {Measure(widthMeasureSpec, heightMeasureSpec);itemWidth = Width();itemHight = Height() / 26f;}/*** 画图*/@Overrideprotected void onDraw(Canvas canvas) {Draw(canvas);for (int i = 0; i < indexArr.length; i++) {if (i != index) {// 如果i不等于选中的item时paint.setColor(Color.BLACK);paint.setTextSize(16);} else {paint.setColor(Color.RED);// 当前操作的字母paint.setTextSize(25);}String word = indexArr[i];// 得到word的宽高Rect bounds = new Rect();TextBounds(word, 0, word.length(), bounds);int wordWidth = bounds.width();int wordHight = bounds.height();// 定义左下角的坐标float x = itemWidth / 2 - wordWidth / 2;float y = itemHight / 2 + wordHight / 2 + i * itemHight;// 画出文本canvas.drawText(word, x, y, paint);}}private int index = -1;// 操作的字母下标@Overridepublic boolean onTouchEvent(MotionEvent event) {switch (Action()) {case MotionEvent.ACTION_DOWN:// 按下case MotionEvent.ACTION_MOVE:// 移动float eventY = Y();int eventindex = (int) (eventY / itemHight);if (index != eventindex) {// 如果操作的index变化了// 强制更新invalidate();index = eventindex;// 通知activity更新textViewif (onIndexChangeListener != null) {if(index<26&&index>0){onIndexChangeListener.OnIndexChanged(indexArr[index]);}}}break;case MotionEvent.ACTION_UP:index = -1;invalidate();//当离开的时候if (onIndexChangeListener != null) {
// onIndexChangeListener.OnUp();}break;default:break;}return true;// 消费}/*** 定义一个接口* * @author 李帅帅*/private OnIndexChangeListener onIndexChangeListener;public interface OnIndexChangeListener {// 当操作的下标改变时,按下时调用public void OnIndexChanged(String word);
// //当离开时调用
// public void OnUp();}public void setOnIndexChangeListener(OnIndexChangeListener onIndexChangeListener) {IndexChangeListener = onIndexChangeListener;}}
第一步我们写一个类来继承View 然后在重写测量方法。再次方法中获得item的宽高
@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {Measure(widthMeasureSpec, heightMeasureSpec);itemWidth = Width();itemHight = Height() / 26f;}
第二步:就到我们从写绘制的方法了,在此方法中我们根据选中角标的位置来让绘制字母颜色,以及字母的宽高
private int index = -1;// 操作的字母下标
@Overrideprotected void onDraw(Canvas canvas) {Draw(canvas);for (int i = 0; i < indexArr.length; i++) {if (i != index) {// 如果i不等于选中的item时paint.setColor(Color.BLACK);paint.setTextSize(16);} else {paint.setColor(Color.RED);// 当前操作的字母paint.setTextSize(25);}String word = indexArr[i];// 得到word的宽高Rect bounds = new Rect();TextBounds(word, 0, word.length(), bounds);int wordWidth = bounds.width();int wordHight = bounds.height();// 定义左下角的坐标float x = itemWidth / 2 - wordWidth / 2;float y = itemHight / 2 + wordHight / 2 + i * itemHight;// 画出文本canvas.drawText(word, x, y, paint);}}
第三步: 也是最为重要的一步,就是onTouchEvent此方法了。在此方法中我们会判断down move up ,当我们按下和移动的时候动态的获得Y/itemheight ,这就是我们选中字母的坐标,如果选中的角标变化了,那么就调用这个invalidate();方法,让其强制重绘,当然在此方法中我们会写一个接口,供页面回调,也是参照源码监听来写的,up的时候也让其强制重绘,记得角标改成非法值.
@Overridepublic boolean onTouchEvent(MotionEvent event) {switch (Action()) {case MotionEvent.ACTION_DOWN:// 按下case MotionEvent.ACTION_MOVE:// 移动float eventY = Y();int eventindex = (int) (eventY / itemHight);if (index != eventindex) {// 如果操作的index变化了// 强制更新invalidate();index = eventindex;// 通知activity更新textViewif (onIndexChangeListener != null) {if(index<26&&index>0){onIndexChangeListener.OnIndexChanged(indexArr[index]);}}}break;case MotionEvent.ACTION_UP:index = -1;invalidate();//当离开的时候if (onIndexChangeListener != null) {
// onIndexChangeListener.OnUp();}break;default:break;}return true;// 消费}
最后这个是我们写的接口
/*** 定义一个接口* * @author 李帅帅*/private OnIndexChangeListener onIndexChangeListener;public interface OnIndexChangeListener {// 当操作的下标改变时,按下时调用public void OnIndexChanged(String word);
// //当离开时调用
// public void OnUp();}public void setOnIndexChangeListener(OnIndexChangeListener onIndexChangeListener) {IndexChangeListener = onIndexChangeListener;}
/*** 页面一* * @author admin* */
public class OneFragment extends Fragment {private TextView mTextView;private QuickIndexView mQIV;private ListView mListView;private List<Friend> data = new ArrayList<Friend>();private FriendAdapter adapter;private Context mContext;private Handler handler = new Handler() {public void handleMessage(android.os.Message msg) {// 隐藏自己mTextView.setVisibility(View.GONE);}};public OneFragment(FragmentActivity mContext) {this.mContext = mContext;}@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {View view = inflater.inflate(R.layout.fragment_one, container, false);initData();initViews(view);setListener();return view;}/*** 初始化试图*/private void initViews(View view) {// 初始化mTextView = (TextView) view.findViewById(R.id.tv_main_word);mListView = (ListView) view.findViewById(R.id.lv_main);mQIV = (QuickIndexView) view.findViewById(R.id.qiv_main);// 显示列表adapter = new FriendAdapter(mContext, data);mListView.setAdapter(adapter);}/*** 设置监听*/private void setListener() {// 设置监听mQIV.setOnIndexChangeListener(new QuickIndexView.OnIndexChangeListener() {@Overridepublic void OnIndexChanged(String word) {mTextView.setText(word);mTextView.setVisibility(View.VISIBLE);// 移除未处理的消息veCallbacksAndMessages(null);handler.sendEmptyMessageDelayed(1, 1000);// 遍历datafor (int i = 0; i < data.size(); i++) {// 得到首字母String firstPinYin = (i).getPinyin().substring(0, 1);if (word.equals(firstPinYin)) {mListView.setSelection(i);return;}}}});//设置点击监听mListView.setOnItemClickListener(new OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> arg0, View arg1, int arg2,long arg3) {Toast.makeText(mContext, (arg2).getName(), 0).show();}});}/*** 准备数据*/private void initData() {data.add(new Friend("张晓飞"));data.add(new Friend("杨光福"));data.add(new Friend("胡继群"));data.add(new Friend("刘畅"));data.add(new Friend("钟泽兴"));data.add(new Friend("尹革新"));data.add(new Friend("安传鑫"));data.add(new Friend("张骞壬"));data.add(new Friend("温松"));data.add(new Friend("李凤秋"));data.add(new Friend("刘甫"));data.add(new Friend("娄全超"));data.add(new Friend("张猛"));data.add(new Friend("王英杰"));data.add(new Friend("李振南"));data.add(new Friend("孙仁政"));data.add(new Friend("唐春雷"));data.add(new Friend("牛鹏伟"));data.add(new Friend("姜宇航"));data.add(new Friend("刘挺"));data.add(new Friend("张洪瑞"));data.add(new Friend("张建忠"));data.add(new Friend("侯亚帅"));data.add(new Friend("刘帅"));data.add(new Friend("乔竞飞"));data.add(new Friend("徐雨健"));data.add(new Friend("吴亮"));data.add(new Friend("王兆霖"));data.add(new Friend("阿三"));Collections.sort(data);}}
注意:我这里是接着上一篇架构的第一个OneFragment写的,如果是Activity页面,那么onCreateView就相当于onCreate方法,就是加载一个布局,然后其他类似.
<RelativeLayout xmlns:android=""xmlns:tools=""android:layout_width="match_parent"android:layout_height="match_parent"tools:context="${relativePackage}.${activityClass}" ><ListView
android:id="@+id/lv_main"android:layout_width="match_parent"android:layout_height="match_parent" ></ListView>&le.fragmenttest.views.QuickIndexView
android:id="@+id/qiv_main"android:layout_width="30dp"android:layout_height="match_parent"android:layout_alignParentRight="true"android:background="@android:color/transparent" /><TextView
android:id="@+id/tv_main_word"android:layout_width="100dp"android:layout_height="100dp"android:layout_centerHorizontal="true"android:layout_centerVertical="true"android:background="#66666666"android:text="A" android:textColor="#EADAA9"android:textSize="40sp"android:gravity="center"android:visibility="gone"/></RelativeLayout>
import java.util.List;ample.fragmenttest.R;
del.Friend;t.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;public class FriendAdapter extends BaseAdapter {private List<Friend> mDatas;private Context mContext;public FriendAdapter(Context mContext, List<Friend> data) {mDatas = data;this.mContext = mContext;}@Overridepublic int getCount() {return mDatas.size();}@Overridepublic Object getItem(int position) {(position);}@Overridepublic long getItemId(int position) {return 0;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ViewHolder holder = null;if (convertView == null) {holder = new ViewHolder();convertView = View.inflate(mContext, R.layout.item_one_fragment, null);holder.wordTV = (TextView) convertView .findViewById(R.id.tv_main_word);holder.nameTV = (TextView) convertView .findViewById(R.id.tv_item_name);convertView.setTag(holder);} else {holder = (ViewHolder) Tag();}Friend friend = (position);String word = Pinyin().substring(0, 1);holder.wordTV.setText(word);holder.nameTV.Name());// 如果下标为0,那么让其显示if (position == 0) {holder.wordTV.setVisibility(View.VISIBLE);} else {// 取出上一个friend,并得到第一个wordString preWord = (position - 1).getPinyin().substring(0, 1);if (word.equals(preWord)) {// 如果相同,那么就隐藏holder.wordTV.setVisibility(View.GONE);} else {// 如果不同,显示holder.wordTV.setVisibility(View.VISIBLE);}}return convertView;}class ViewHolder {public TextView wordTV;public TextView nameTV;}}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android=""android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical" ><TextView
android:id="@+id/tv_main_word"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="A"android:textSize="18sp"android:background="#66666666" android:padding="5dp"/><TextView
android:id="@+id/tv_item_name"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="阿三"android:textSize="18sp"android:padding="5dp"/></LinearLayout>
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.ption.BadHanyuPinyinOutputFormatCombination;/*** 将汉字转换为拼音* @author 李帅帅**/
public class PinYinUtils {/*** 得到指定汉字的拼音* 注意:不应该被频繁调用,它消耗一定内存* @param hanzi* @return*/public static String getPinYin(String hanzi){String pinyin = "";HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();//控制转换是否大小写,是否带音标format.setCaseType(HanyuPinyinCaseType.UPPERCASE);//大写format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);//由于不能直接对多个汉字转换,只能对单个汉字转换char[] arr = CharArray();for (int i = 0; i < arr.length; i++) {if(Character.isWhitespace(arr[i]))continue;//如果是空格,则不处理,进行下次遍历//汉字是2个字节存储,肯定大于127,所以大于127就可以当为汉字转换if(arr[i]>127){try {//由于多音字的存在,单 dan shanString[] pinyinArr = HanyuPinyinStringArray(arr[i], format);if(pinyinArr!=null){pinyin += pinyinArr[0];}else {pinyin += arr[i];}} catch (BadHanyuPinyinOutputFormatCombination e) {e.printStackTrace();//不是正确的汉字pinyin += arr[i];}}else {//不是汉字,pinyin += arr[i];}}return pinyin;}
}
本文发布于:2024-01-29 11:22:33,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170649855914922.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |