Andriod实现快速索引条
来源:互联网 发布:网络平台运营方案 编辑:程序博客网 时间:2024/05/18 13:24
1,首先这个类是绘制右侧自定义索引条的:
/** * Created by felix on 15/4/24. */public class QuickIndexBar extends View { public QuickIndexBar(Context context) { super(context); init(); } public QuickIndexBar(Context context, AttributeSet attrs) { super(context, attrs); init(); } public QuickIndexBar(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } //以26个字母作为索引 String[] indexs = 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 paint; private int cellWidth, cellHeight; private void init() { paint = new Paint(); paint.setTextSize(10); paint.setColor(Color.RED); //paint.setTypeface(Typeface.DEFAULT_BOLD); paint.setAntiAlias(true); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (cellHeight == 0) cellHeight = getMeasuredHeight() / indexs.length; if (cellWidth == 0) cellWidth = getMeasuredWidth(); //分别画26个字母 for (int i = 0; i < indexs.length; i++) { if (i == lastIndex) { //正在touch的位置 需要更加人性化的交互 paint.setTextSize(80); paint.setColor(Color.GRAY); } else { paint.setTextSize(40); paint.setColor(Color.BLUE); } //先测量用此画笔画字母的大小,用一个矩形把它包裹起来,这样方便计算字母的高度 Rect bounds = new Rect(); paint.getTextBounds(indexs[i], 0, indexs[i].length(), bounds); //计算画每个字母的起始坐标 float x = cellWidth / 2 - paint.measureText(indexs[i]) / 2; float y = cellHeight / 2 + bounds.height() / 2 + i * cellHeight; canvas.drawText(indexs[i], x, y, paint); } } private int lastIndex = -1; @Override public boolean onTouchEvent(MotionEvent event) { int x = (int) event.getX();// if (x >= 0 && x <= cellWidth) { //只对quickindexbar的触摸事件有效// return false;// } int y = (int) event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_MOVE: if (isSameIndex(y / cellHeight)) break; //安全检查 if (y >= 0 && (y / cellHeight) < indexs.length) { String word = indexs[((int) (y / cellHeight))]; lastIndex = y / cellHeight; if (mIndexChangedListener != null) { mIndexChangedListener.indexChanged(word); } } break; case MotionEvent.ACTION_UP: lastIndex = -1; break; default: break; } //重新调用onDraw invalidate(); //自行处理触摸事件,不向上传递 return true; } /** * 当前的索引位置是否和上一个相等 */ private boolean isSameIndex(int currIndex) { return lastIndex == currIndex; } private IndexChangedListener mIndexChangedListener; public void setIndexChangedListener(IndexChangedListener indexChangedListener) { mIndexChangedListener = indexChangedListener; } public interface IndexChangedListener { void indexChanged(String word); }}
2,这个类是自定义索引条与本人项目的结合/////////////////////////下面的是结合的部分,其他是自己项目的内容
package cn.sh.steel;import android.content.Context;import android.content.Intent;import android.os.AsyncTask;import android.os.Bundle;import android.os.Handler;import android.text.Editable;import android.text.TextUtils;import android.util.Log;import android.view.KeyEvent;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.view.inputmethod.EditorInfo;import android.widget.ArrayAdapter;import android.widget.EditText;import android.widget.ListView;import android.widget.TextView;import android.widget.Toast;import com.google.gson.reflect.TypeToken;import org.apache.commons.lang3.ArrayUtils;import java.util.Collections;import java.util.Comparator;import java.util.List;import cn.sh.steel.bean.Cust;import cn.sh.steel.bean.EnumValue;import pysh.GSON;import pysh.HttpResult;import pysh.Utils;public class CustListActivity extends BaseActivity { LayoutInflater inflater; ListView listView; List<Cust> custList; EditText keyword; String selected;/////////////////////////////////////////////////////////////////////////// private QuickIndexBar mQuickIndexBar; private TextView mLabel; //在屏幕中间显示的字母放大版标签 private static final int DEFAULT_DELAY = 1200; private static final String TAG = "CustListActivity"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.page_cust_list); ///////////////////////////////////////////////////////// // search(); mQuickIndexBar = (QuickIndexBar) findViewById(R.id.quickbar); mLabel = (TextView) findViewById(R.id.showLabel); listView = (ListView) findViewById(R.id.cust_list); keyword = (EditText) findViewById(R.id.keyword); keyword.setOnEditorActionListener(new TextView.OnEditorActionListener() { @Override public boolean onEditorAction(TextView textView, int actionId, KeyEvent keyEvent) { if (actionId == EditorInfo.IME_ACTION_SEARCH || actionId == EditorInfo.IME_ACTION_SEND || actionId == EditorInfo.IME_ACTION_DONE) { hideKeyboard(); new DataTask().execute("uid", getUser().getUser_id(), "keyword", keyword.getText().toString()); return true; } return false; } }); String order = getIntent().getStringExtra("order"); if (Utils.isNotEmpty(order)) { selected = ""; } } @Override protected void onResume() { super.onResume(); new DataTask().execute("uid", getUser().getUser_id()); } class DataTask extends AsyncTask<String, Integer, HttpResult> { @Override protected void onPostExecute(HttpResult result) { if (result.getCode() == 1) { String json = result.getText(); custList = GSON.toList(json, new TypeToken<List<Cust>>() { }.getType()); ////////////////////////////////////////////////////////////////// //将集合中的汉字转换成拼音并排序 for (int i =0;i<custList.size();i++){ // Log.d("CustListActivity",custList.get(i).getCust_name()); PinyinUtils.getPinyin(custList.get(i).getCust_name()); //Log.d("CustListActivity",PinyinUtils.getPinyin(custList.get(i).getCust_name())); } Collections.sort(custList,new Comparator<Cust>() { @Override public int compare(Cust lhs, Cust rhs) { try { return (PingYinUtil.getPingYin(lhs.getCust_name()) .toUpperCase()).compareTo(PingYinUtil .getPingYin(rhs.getCust_name()).toUpperCase()); } catch (Exception e) { e.printStackTrace(); return 0; } } });// PinyinComparator comparator = new PinyinComparator();// Collections.sort(custList, comparator); Log.d("CustListActivity",custList.toString()); CustListActivity.CustRowAdapter adapter = new CustListActivity.CustRowAdapter(CustListActivity.this, R.layout.cust_list_row); adapter.clear(); adapter.addAll(custList); listView.setAdapter(adapter); ///////////////////////////////////////////////////////////////// mQuickIndexBar.setIndexChangedListener(new QuickIndexBar.IndexChangedListener() { @Override public void indexChanged(String word) { //Log.i(TAG, word); showIndexLabel(word); for (int i=0;i<custList.size();i++) { String indexWord= custList.get(i).getCust_name().charAt(0)+""; String pinYin= PingYinUtil.getPingYin(indexWord); String firstLetter= pinYin.charAt(0)+""; String s = firstLetter.toUpperCase(); Log.i(TAG, s); if (word.equals(s)) { listView.setSelection(i); break; } } } }); } } @Override protected HttpResult doInBackground(String... args) { String order = getIntent().getStringExtra("order"); if (Utils.isNotEmpty(order)) { args = ArrayUtils.addAll(args,"status","1"); } HttpResult result = getHttpExecutor().get(CONSTANT.host + CONSTANT.url_cust_list, args); return result; } } class CustRowAdapter extends ArrayAdapter<Cust> { public CustRowAdapter(Context context, int resource) { super(context, resource); } @Override public View getView(int position, View item, ViewGroup parent) { if (item == null) { Log.i("item is null", "yes"); inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); item = inflater.inflate(R.layout.cust_list_row, null); } final Cust cust = custList.get(position); TextView tv_row_name = (TextView) item.findViewById(R.id.row_name); tv_row_name.setText(cust.getCust_name()); TextView tv_row_mobile = (TextView) item.findViewById(R.id.row_mobile); tv_row_mobile.setText(cust.getCust_id()); TextView tv_row_type = (TextView) item.findViewById(R.id.row_type); String text = EnumValue.CustType.instances(cust.getCust_type()).getName(); if (cust.getCust_type() == EnumValue.CustType.COMPANY.getCode() && Utils.isNotEmpty(cust.getCust_scale())) { text = text + " " + cust.getCust_scale(); } tv_row_type.setText(text); TextView tv_row_address = (TextView) item.findViewById(R.id.row_address); tv_row_address.setText(cust.getCust_address()); ////////////////////////////////////////////////////////// //判断是否显示当前标题栏 TextView tv_row_tag = (TextView) item.findViewById(R.id.tv_lv_item_tag); String currIndexWord = cust.getCust_name().charAt(0) + ""; //char firstLetter= PinyinUtils.getPinyin(currIndexWord).charAt(0); //String currIndexWord = tv_row_tag.getText()+""; String firstWord= PingYinUtil.getFirstSpell(currIndexWord); if (position > 0) { String lastIndexWord = getItem(position - 1).getCust_name().charAt(0) + ""; String firstWord2= PingYinUtil.getFirstSpell(lastIndexWord); //char firstLetter1= PinyinUtils.getPinyin(currIndexWord).charAt(0); if (firstWord.equals(firstWord2)) { tv_row_tag.setVisibility(View.GONE); } else { tv_row_tag.setVisibility(View.VISIBLE); tv_row_tag.setText(firstWord); } } else { tv_row_tag.setVisibility(View.VISIBLE); tv_row_tag.setText(firstWord); } item.findViewById(R.id.cust_status0).setVisibility(View.GONE); item.findViewById(R.id.cust_status1).setVisibility(View.GONE); if (EnumValue.CustStatus.FORMAL.getCode()== cust.getStatus()){ item.findViewById(R.id.cust_status1).setVisibility(View.VISIBLE); }else{ item.findViewById(R.id.cust_status0).setVisibility(View.VISIBLE); } item.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View row) { if (selected == null) { Intent intent = new Intent(getApplicationContext(), UserActivity.class); intent.putExtra("from_other_one", "from_other_one"); intent.putExtra("cust_id", cust.getCust_id()); startActivity(intent); } else { if (EnumValue.CustStatus.FORMAL.getCode() == cust.getStatus()) { View selectedView = row.findViewById(R.id.selected); selectedView.setVisibility(View.VISIBLE); Intent intent = new Intent(getApplicationContext(), ProductListActivity.class); intent.putExtra("custjson", GSON.toJson(cust)); intent.putExtra("order", "order"); intent.putExtra("order_from_saller", "order_from_saller"); startActivity(intent); } else { Toast.makeText(CustListActivity.this, "此客户未审核通过,不能下单", Toast.LENGTH_SHORT).show(); } } } }); return item; } } ////////////////////////////////////////// private Handler mHandler = new Handler(); private void showIndexLabel(String word) { mLabel.setVisibility(View.VISIBLE); mLabel.setText(word); mHandler.removeCallbacksAndMessages(null); //移除所有消息队列 mHandler.postDelayed(new Runnable() { //发送延时消息 @Override public void run() { mLabel.setVisibility(View.GONE); } }, DEFAULT_DELAY); }}
3,对应布局文件如下:
<?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="wrap_content" ><LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#fff" android:orientation="vertical"> <fragment android:id="@+id/title" android:layout_width="match_parent" android:layout_height="46dp" android:name="cn.sh.steel.fragment.TitleFragment"/> <LinearLayout android:id="@+id/query_wrap" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:background="@color/light_gray2" android:weightSum="10"> <ImageView android:layout_width="26dp" android:layout_height="26dp" android:src="@drawable/glass" android:layout_gravity="center_vertical" android:paddingLeft="10dp"/> <EditText android:id="@+id/keyword" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="姓名/手机" android:background="@drawable/searchbox" android:textSize="16sp" android:singleLine="true" android:imeOptions="actionDone" android:textColor="#333"/> </LinearLayout> <LinearLayout android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent"> <ListView android:id="@+id/cust_list" android:layout_height="match_parent" android:dividerHeight="6dp" android:divider="@color/light_gray2" android:layout_toRightOf="@+id/showLabel" android:layout_toEndOf="@+id/showLabel" android:layout_weight="18" android:layout_width="0dp" android:footerDividersEnabled="true"/> <cn.sh.steel.QuickIndexBar android:id="@+id/quickbar" android:layout_weight="1" android:layout_width="0dp" android:layout_height="match_parent" android:layout_alignParentRight="true" android:layout_alignParentEnd="true" android:background="@color/white" /> </LinearLayout></LinearLayout> <!--中间放大部分显示的文字--> <TextView android:id="@+id/showLabel" android:layout_width="120dp" android:layout_height="120dp" android:textColor="@color/radio_button_selected_color" android:visibility="gone" android:gravity="center" android:layout_centerInParent="true" android:textSize="50sp" android:background="@drawable/shap" android:padding="5dp" android:text="A" /></RelativeLayout>
4,下面这个类是汉字转拼音的类
package cn.sh.steel;import android.util.Log;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.HanyuPinyinVCharType;import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;/** * 拼音工具类 * */public class PingYinUtil { /** * 将字符串中的中文转化为拼音,其他字符不变 * * @param inputString * @return */ public static String getPingYin(String inputString) { HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat(); format.setCaseType(HanyuPinyinCaseType.UPPERCASE); format.setToneType(HanyuPinyinToneType.WITHOUT_TONE); format.setVCharType(HanyuPinyinVCharType.WITH_V); char[] input = inputString.trim().toCharArray(); String output = ""; try { for (int i = 0; i < input.length; i++) { if (Character.toString(input[i]).matches( "[\\u4E00-\\u9FA5]+")) { String[] temp = PinyinHelper.toHanyuPinyinStringArray( input[i], format); if (inputString.equals("长豆角")&&i==0){ output += temp[1]; }else { output += temp[0]; } } else output += Character.toString(input[i]); } } catch (BadHanyuPinyinOutputFormatCombination e) { e.printStackTrace(); } return output; } /** * 获取汉字串拼音首字母,英文字符不变 * * @param chinese * 汉字串 * @return 汉语拼音首字母 */ public static String getFirstSpell(String chinese) { StringBuffer pybf = new StringBuffer(); char[] arr = chinese.toCharArray(); HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat(); defaultFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE); defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE); for (int i = 0; i < arr.length; i++) { if (arr[i] > 128) { try { String[] temp = PinyinHelper.toHanyuPinyinStringArray( arr[i], defaultFormat); if (temp != null) { if (chinese.equals("长豆角")&&i==0){ pybf.append(temp[1].charAt(0)); }else { pybf.append(temp[0].charAt(0)); } } } catch (BadHanyuPinyinOutputFormatCombination e) { e.printStackTrace(); } } else { pybf.append(arr[i]); } } return pybf.toString().replaceAll("\\W", "").trim(); } /** * 获取汉字串拼音,英文字符不变 * * @param chinese * 汉字串 * @return 汉语拼音 */ public static String getFullSpell(String chinese) { StringBuffer pybf = new StringBuffer(); char[] arr = chinese.toCharArray(); HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat(); defaultFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE); defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE); for (int i = 0; i < arr.length; i++) { if (arr[i] > 128) { try { pybf.append(PinyinHelper.toHanyuPinyinStringArray(arr[i], defaultFormat)[0]); } catch (BadHanyuPinyinOutputFormatCombination e) { e.printStackTrace(); } } else { pybf.append(arr[i]); } } return pybf.toString(); } /** * 判断是否以字母开头 */ public static boolean isStartWithLetter(String s) { String regex = "^[A-Za-z]+$"; if (s.matches(regex)) { return true; } else { return false; } } /** * 获取T9搜索的数字 * String search:字母串 * boolean status:字母串字母是否重复 * String str:T9数字 */ public static String getNum(String search, boolean status) { String str = ""; for (int i = 0; i < search.length(); i++) { String c = search.charAt(i) + ""; if (c.equals("1")) { str = str + "1"; if (status) { i = i + 1; } continue; } else if (c.equals("A") || c.equals("B") || c.equals("C") || c.equals("2") || c.equals("a") || c.equals("b") || c.equals("c")) { str = str + "2"; if (status) { i = i + 1; } continue; } else if (c.equals("D") || c.equals("E") || c.equals("F") || c.equals("3") || c.equals("d") || c.equals("e") || c.equals("f")) { str = str + "3"; if (status) { i = i + 1; } continue; } else if (c.equals("G") || c.equals("H") || c.equals("I") || c.equals("4") || c.equals("g") || c.equals("h") || c.equals("i")) { str = str + "4"; if (status) { i = i + 1; } continue; } else if (c.equals("J") || c.equals("K") || c.equals("L") || c.equals("5") || c.equals("j") || c.equals("k") || c.equals("l")) { str = str + "5"; if (status) { i = i + 1; } continue; } else if (c.equals("M") || c.equals("N") || c.equals("O") || c.equals("6") || c.equals("m") || c.equals("n") || c.equals("o")) { str = str + "6"; if (status) { i = i + 1; } continue; } else if (c.equals("P") || c.equals("Q") || c.equals("R") || c.equals("S") || c.equals("7") || c.equals("p") || c.equals("q") || c.equals("r") || c.equals("s")) { str = str + "7"; if (status) { i = i + 1; } continue; } else if (c.equals("T") || c.equals("U") || c.equals("V") || c.equals("8") || c.equals("t") || c.equals("u") || c.equals("v")) { str = str + "8"; if (status) { i = i + 1; } continue; } else if (c.equals("W") || c.equals("X") || c.equals("Y") || c.equals("Z") || c.equals("9") || c.equals("w") || c.equals("x") || c.equals("y") || c.equals("z")) { str = str + "9"; if (status) { i = i + 1; } continue; } else if (c.equals("0")) { str = str + "0"; if (status) { i = i + 1; } continue; } } return str; } }
一共就这么多,大家结合自己的项目可以适当的运用!
0 0
- Andriod实现快速索引条
- 联系人界面快速索引条
- 滑动索引条实现
- 快速索引实现
- 仿通讯录快速索引的实现原理(包括中间的字母图和右边的索引条),例IndexableListView
- Android快速索引条控件QuickIndexBar
- 快速索引的简单实现
- android快速索引的实现
- Android实现快速索引详解
- 自定义View:快速索引实现
- 通讯录索引条的功能实现
- Android自定义View实现字母索引条
- 实现ListView A~Z快速索引
- 实现ListView A~Z快速索引
- Android仿微信实现快速索引选择联系人
- 关于android实现fastindexbar(快速索引)详解
- Android 自定义View-实现快速索引
- ListView实现城市快速索引功能
- 基本算法
- hdu 5883 The Best Path 欧拉路径 & 欧拉回路 并查集
- 一个基于rduino的智能温控系统
- POJ 1019 Number Sequence (瞎搞)
- IDoc 状态
- Andriod实现快速索引条
- 手把手教你手机丢失后支付宝微信里的处理方法
- odoo之视图
- NOJ 1135 Missile dp 最长上升子序列变形 双dp
- 2016年安全好用微信开通检测软件
- NodeJs洗牌算法
- spi的时序图
- MySQL 5.6 for Windows 解压缩版配置安装
- IOS 基于ffmpeg VR播放器