類似於Android中通訊錄的實現
開發中難免會遇到類似於通訊錄的開發,做出來供大家參考。
實現圖
圖一爲點擊右方的字母實現圖,鏈表會到F的那個條目
圖二爲效果圖
具體代碼
這裏需要導入一個 pinyin4j-2.5.0.jar 包是將漢字轉爲拼音的jar包和一個 nineoldandroids-2.4.0.jar包這是我的代碼中用的一個動畫效果
首先主頁面
QuickIndexBarActivity.java
package com.example.custom_view; import android.os.Bundle; import android.os.Handler; import android.support.annotation.Nullable; import android.support.v7.app.AppCompatActivity; import android.view.Window; import android.widget.ListView; import android.widget.TextView; import com.nineoldandroids.view.ViewHelper; import com.nineoldandroids.view.ViewPropertyAnimator; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class QuickIndexBarActivity extends AppCompatActivity { private MyQuickIndexBar mQuickIndexBar; private ListView mLv; private List<PinYinInfo> list = new ArrayList<PinYinInfo>(); private TextView mTv_window; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); supportRequestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_quick_index_bar); initView(); } private void initView() { mLv = findViewById(R.id.lv); mTv_window = findViewById(R.id.tv_window); mQuickIndexBar = findViewById(R.id.my_quickIndexbar); list = getStrList(); Collections.sort(list); MyAdapter adapter = new MyAdapter(QuickIndexBarActivity.this, list); mLv.setAdapter(adapter); mQuickIndexBar.setOnItemtClickListenner(new MyQuickIndexBar.onItemClickListenner() { @Override public void getOnImtemPosition(String letter) { for (int i = 0; i < list.size(); i++) { String strLetter = list.get(i).getmPinYinName().charAt(0) + ""; if (letter.equalsIgnoreCase(strLetter)) { mLv.setSelection(i); break; } } showCurrentTvWindow(letter); } }); ViewHelper.setScaleX(mTv_window, 0F); ViewHelper.setScaleY(mTv_window, 0F); } private Handler mHandler = new Handler(); private boolean mFlag; private void showCurrentTvWindow(String letter) { if (!mFlag) { mFlag = true; ViewPropertyAnimator.animate(mTv_window).setDuration(450).scaleX(1.0F).start(); ViewPropertyAnimator.animate(mTv_window).setDuration(450).scaleY(1.0F).start(); } mTv_window.setText(letter); mHandler.removeCallbacksAndMessages(null); mHandler.postDelayed(new Runnable() { @Override public void run() { mFlag = false; ViewPropertyAnimator.animate(mTv_window).setDuration(450).scaleX(0.0F).start(); ViewPropertyAnimator.animate(mTv_window).setDuration(450).scaleY(0.0F).start(); } }, 2000); } public List<PinYinInfo> getStrList() { list.add(new PinYinInfo("北京")); list.add(new PinYinInfo("深圳")); list.add(new PinYinInfo("廣州")); list.add(new PinYinInfo("天津")); list.add(new PinYinInfo("河北")); list.add(new PinYinInfo("河南")); list.add(new PinYinInfo("山西")); list.add(new PinYinInfo("湖北")); list.add(new PinYinInfo("湖南")); list.add(new PinYinInfo("遼寧")); list.add(new PinYinInfo("上海")); list.add(new PinYinInfo("寧夏")); list.add(new PinYinInfo("內蒙古")); list.add(new PinYinInfo("重慶")); list.add(new PinYinInfo("四川")); list.add(new PinYinInfo("貴州")); list.add(new PinYinInfo("吉林")); list.add(new PinYinInfo("廣西")); list.add(new PinYinInfo("陝西")); list.add(new PinYinInfo("新疆")); list.add(new PinYinInfo("黑龍江")); list.add(new PinYinInfo("福建")); list.add(new PinYinInfo("江蘇")); list.add(new PinYinInfo("江西")); list.add(new PinYinInfo("安徽")); list.add(new PinYinInfo("大連")); list.add(new PinYinInfo("鄂爾多斯")); list.add(new PinYinInfo("東莞")); list.add(new PinYinInfo("滄州")); list.add(new PinYinInfo("長春")); list.add(new PinYinInfo("成都")); list.add(new PinYinInfo("海南")); list.add(new PinYinInfo("香港")); list.add(new PinYinInfo("北小營")); list.add(new PinYinInfo("臺灣")); list.add(new PinYinInfo("保定")); list.add(new PinYinInfo("包頭")); list.add(new PinYinInfo("北海")); list.add(new PinYinInfo("澳門")); list.add(new PinYinInfo("安陽")); list.add(new PinYinInfo("鞍山")); list.add(new PinYinInfo("西藏")); list.add(new PinYinInfo("安慶")); list.add(new PinYinInfo("浙江")); list.add(new PinYinInfo("雲南")); list.add(new PinYinInfo("甘肅")); list.add(new PinYinInfo("山東")); return list; } }
activity_quick_index_bar.class
<?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" android:orientation="vertical"> <ListView android:id="@+id/lv" android:layout_width="match_parent" android:layout_height="match_parent" android:divider="@color/colorPrimaryDark" android:dividerHeight="0.1dp" android:scrollbars="none"></ListView> <com.example.custom_view.MyQuickIndexBar android:id="@+id/my_quickIndexbar" android:layout_width="30dp" android:layout_height="match_parent" android:layout_alignParentRight="true" android:background="#FF00FF" /> <TextView android:id="@+id/tv_window" android:layout_width="115dp" android:layout_height="115dp" android:layout_centerInParent="true" android:background="@drawable/tv_window_bg" android:gravity="center" android:text="A" android:textSize="40sp" android:textStyle="bold" /> </RelativeLayout>
佈局中MyQuickIndexBar會報錯,這就得看你創的項目名了,自己根據情況修改。
MyQuickIndexBar.java
package com.example.custom_view; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; import android.support.annotation.Nullable; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.view.View; public class MyQuickIndexBar extends View { private String[] mStrArr = {"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"}; public MyQuickIndexBar(Context context) { this(context, null); } public MyQuickIndexBar(Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0); } public MyQuickIndexBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private int mWidth; private float mCellHeight; @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); mWidth = getMeasuredWidth(); mCellHeight = getMeasuredHeight() * 1F / mStrArr.length; } private Paint mPaint; private void init() { mPaint = new Paint(); mPaint.setAntiAlias(true); mPaint.setColor(Color.BLACK); //以文本的中心線爲起始點開始繪製文本 mPaint.setTextAlign(Paint.Align.CENTER); mPaint.setTextSize(50); } @Override protected void onDraw(Canvas canvas) { for (int i = 0; i < mStrArr.length; i++) { float x = mWidth / 2; float y = mCellHeight / 2 + getTextHeight(mStrArr[i]) / 2 + i * mCellHeight + 10; mPaint.setColor(mLastIndex == i ? Color.parseColor("#FFFF00") : Color.BLACK); canvas.drawText(mStrArr[i], x, y, mPaint); } super.onDraw(canvas); } private float getTextHeight(String text) { Rect rect = new Rect(); mPaint.getTextBounds(text, 0, text.length(), rect); return rect.bottom; } private int mLastIndex = -1; @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_MOVE: int index = (int) (event.getY() / mCellHeight); if (index>-1&&index<mStrArr.length) { Log.e("wew", mStrArr[index] + ""); if (mListenner != null) { mListenner.getOnImtemPosition(mStrArr[index]); } } mLastIndex = index; break; case MotionEvent.ACTION_UP: Log.e("assaas", "action_up"); mLastIndex = -1; break; } //重繪 (重新繪製View) invalidate(); return true; } private onItemClickListenner mListenner; public interface onItemClickListenner { void getOnImtemPosition(String letter); } public void setOnItemtClickListenner(onItemClickListenner listenner) { this.mListenner = listenner; } }
MyAdapter.java
package com.example.custom_view; import android.content.Context; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.TextView; import java.util.List; public class MyAdapter extends BaseAdapter { private Context mContext; private List<PinYinInfo> mList; public MyAdapter(Context context, List<PinYinInfo> strList) { this.mContext = context; this.mList = strList; } @Override public int getCount() { return mList.size(); } @Override public Object getItem(int position) { return mList.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { if (convertView == null) convertView = View.inflate(mContext, R.layout.list_item, null); ViewHolder viewHolder = ViewHolder.getViewHolder(convertView); String currentStrLetter = mList.get(position).getmPinYinName().charAt(0) + ""; if (position > 0) { String lastStrLetter = mList.get(position - 1).getmPinYinName().charAt(0) + ""; if (lastStrLetter.equals(currentStrLetter)) { viewHolder.tv_letter.setVisibility(View.GONE); } else { viewHolder.tv_letter.setText(currentStrLetter); viewHolder.tv_letter.setVisibility(View.VISIBLE); } } else { viewHolder.tv_letter.setText(currentStrLetter); viewHolder.tv_letter.setVisibility(View.VISIBLE); } viewHolder.tv_name.setText(mList.get(position).getmName()); return convertView; } public static class ViewHolder { private TextView tv_letter, tv_name; public ViewHolder(View convertView) { tv_letter = convertView.findViewById(R.id.tv_letter); tv_name = convertView.findViewById(R.id.tv_name); } public static ViewHolder getViewHolder(View convertView) { ViewHolder viewHolder = (ViewHolder) convertView.getTag(); if (viewHolder == null) { viewHolder = new ViewHolder(convertView); convertView.setTag(viewHolder); } return viewHolder; } } }
list_item.class
<?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="90dp" android:orientation="vertical"> <TextView android:id="@+id/tv_letter" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#33000000" android:gravity="center_vertical" android:padding="4dp" android:text="A" android:textSize="14sp" android:textStyle="bold" /> <TextView android:id="@+id/tv_name" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:gravity="center_vertical" android:paddingBottom="7dp" android:paddingLeft="4dp" android:paddingTop="7dp" android:text="阿爾山" android:textSize="23sp" /> </LinearLayout>
PinYinlinfo.java
package com.example.custom_view; 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; public class PinYinUtils { public static String getPinYin(String str) { String pinyin = ""; HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat(); format.setCaseType(HanyuPinyinCaseType.UPPERCASE); format.setToneType(HanyuPinyinToneType.WITHOUT_TONE); if (!TextUtils.isEmpty(str)) { char[] mCharArr = str.toCharArray(); if (mCharArr != null && mCharArr.length > 0) { for (int i = 0; i < mCharArr.length; i++) { char c = mCharArr[i]; // TODO UTF-8格式下 1個漢字==2個字節 1個字節(-128----127) if (c > 127) { //不一定是漢字,也不一定是字母 try { String[] strArr = PinyinHelper.toHanyuPinyinStringArray(c, format); pinyin += strArr[0]; } catch (BadHanyuPinyinOutputFormatCombination badHanyuPinyinOutputFormatCombination) { badHanyuPinyinOutputFormatCombination.printStackTrace(); pinyin += c; } } else { //一定不是漢字,有可能是字母或者標點或者數字 pinyin += c; } } } } return pinyin; } }
PinYinUtils.java
package com.example.custom_view; 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; public class PinYinUtils { public static String getPinYin(String str) { String pinyin = ""; HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat(); format.setCaseType(HanyuPinyinCaseType.UPPERCASE); format.setToneType(HanyuPinyinToneType.WITHOUT_TONE); if (!TextUtils.isEmpty(str)) { char[] mCharArr = str.toCharArray(); if (mCharArr != null && mCharArr.length > 0) { for (int i = 0; i < mCharArr.length; i++) { char c = mCharArr[i]; // TODO UTF-8格式下 1個漢字==2個字節 1個字節(-128----127) if (c > 127) { //不一定是漢字,也不一定是字母 try { String[] strArr = PinyinHelper.toHanyuPinyinStringArray(c, format); pinyin += strArr[0]; } catch (BadHanyuPinyinOutputFormatCombination badHanyuPinyinOutputFormatCombination) { badHanyuPinyinOutputFormatCombination.printStackTrace(); pinyin += c; } } else { //一定不是漢字,有可能是字母或者標點或者數字 pinyin += c; } } } } return pinyin; } }
終於完成了,有什麼問題可以評論!