效果图:
这样写Layout:
<?xml version="1.0" encoding="utf-8"?
> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:rcm="http://schemas.android.com/apk/res/com.ringcentral.android" android:id="@+id/contact_list_view" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/bgColorMain" android:orientation="vertical" > <FrameLayout android:layout_width="match_parent" android:layout_height="match_parent" > <ListView android:id="@android:id/list" android:layout_width="match_parent" android:layout_height="match_parent" android:cacheColorHint="@android:color/transparent" android:divider="@null" android:listSelector="@drawable/bg_list_item_selector" /> <com.example.view.<strong>SectionIndexerView //这个是右边的导航</strong> android:id="@+id/section_indexer_view" android:layout_width="70dip" android:layout_height="fill_parent" android:layout_gravity="right" android:layout_marginBottom="4dip" android:layout_marginRight="6dip" android:layout_marginTop="4dip" android:textSize="12.0sp" /> <<strong>TextView //这个是中间的字母提示</strong> android:id="@+id/section_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:background="@drawable/section_text_bg" android:gravity="center" android:textColor="#FFFFFF" android:textSize="40sp" android:visibility="gone" /> </FrameLayout> <RelativeLayout android:id="@+id/no_contact_indication" android:layout_width="match_parent" android:layout_height="match_parent" > <TextView android:id="@+id/emptyListText" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:singleLine="true" android:text="No Contacts" android:textColor="@color/text_no_items" android:textSize="20sp" /> <ProgressBar android:id="@+id/loading" style="@style/RCMProgressBar" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:visibility="gone" /> </RelativeLayout> </LinearLayout>
关于SectionIndexerView 的写法:
public class SectionIndexerView extends View{ public static final String TAG = SectionIndexerView.class.getSimpleName(); private static final boolean DEBUG = true; /** 写文字的画笔 */ private Paint mTextPaint; /** 指定view的宽度 */ private int mViewWidth = 0; /** 指定view的高度 */ private int mViewHeight = 0; /** 每一个文字的高度 */ private float mPerTextHeight; /** 是否是按下状态 */ private boolean mIsPressed = false; /** 关联的listview */ private ListView mListview = null; /** 关联的indexer */ private SectionIndexer mIndexer; /** 关联的textview */ private TextView mView = null; /** 依照A-Z排序的section */ private String[] mSectionIndexerText = { "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 static final float TEXTSIZE_RATIO = 0.84f; /** 默认的字体大小常量 */ private static final int CHAR_WIDTH = 12; /** 背景的透明度 */ private static final int BG_ALPHA = 153; /** 背景的圆角弧度 */ private static final float BG_RADIAN = 20f; /** 默认的字体大小 */ private int mCharwidth = CHAR_WIDTH; /** Context */ private Context mContext = null; /** * 构造函数 * * @param context * Context */ public SectionIndexerView(Context context) { super(context); init(context); } /** * 构造函数 * * @param context * Context * @param attributeSet * AttributeSet */ public SectionIndexerView(Context context, AttributeSet attributeSet) { super(context, attributeSet); init(context); } /** * 初始化基本信息 * * @param context * Context */ private void init(Context context) { mContext = context; mCharwidth = (int) (mCharwidth * mContext.getResources().getDisplayMetrics().density); this.mTextPaint = new Paint(); this.mTextPaint.setAntiAlias(true); this.mTextPaint.setColor(-1); } /** * 初始化SectionIndexer,指定listview,indexer及显示section的textview * * @param listview * 关联的listview * @param indexer * 关联的SectionIndexer * @param view * 关联的TextView */ public void init(ListView listview, SectionIndexer indexer, TextView view) { this.mListview = listview; this.mIndexer = indexer; this.mView = view; } @Override protected void onDraw(Canvas paramCanvas) { Paint localPaint = new Paint(); localPaint.setAntiAlias(true); this.mTextPaint.setColor(Color.parseColor("#75797d")); if (this.mIsPressed) { localPaint.setColor(Color.parseColor("#838a98")); localPaint.setAlpha(BG_ALPHA); } else { localPaint.setAlpha(0); } this.mTextPaint.setTextSize(this.mViewHeight * TEXTSIZE_RATIO / mSectionIndexerText.length); System.out.println("==textSize="+(this.mViewHeight * TEXTSIZE_RATIO / mSectionIndexerText.length)); System.out.println("====mViewWidth="+mViewWidth+"mCharWidth="+mCharwidth); //paramCanvas.drawRoundRect是画背景,BG_RADIAN为弯曲的弧度 paramCanvas.drawRoundRect(new RectF(50, 0.0F, this.mViewWidth, this.mViewHeight), BG_RADIAN, BG_RADIAN, localPaint); //这个textPointX为 int textPointX = 140; //textPointY为写text的Y的位置 float textPointY = (this.mPerTextHeight - this.mTextPaint.ascent()) / 2.0F; int sectionslength = this.mSectionIndexerText.length; int currentSection = 0; int currentHeight = 0; while (true) { if (currentSection >= sectionslength) { break; } //(mCharwidth - (int) this.mTextPaint.measureText(this.mSectionIndexerText[currentSection])) / 2 //这样写的原因是使每一个字母居中对齐 paramCanvas.drawText( this.mSectionIndexerText[currentSection], textPointX + (mCharwidth - (int) this.mTextPaint .measureText(this.mSectionIndexerText[currentSection])) / 2, textPointY + (3.0F + currentHeight * this.mPerTextHeight), this.mTextPaint);// SUPPRESS CHECKSTYLE : magic number ++currentHeight; ++currentSection; } } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int width = View.MeasureSpec.getSize(widthMeasureSpec); this.mViewWidth = width; int height = View.MeasureSpec.getSize(heightMeasureSpec); this.mViewHeight = height; setMeasuredDimension(this.mViewWidth, this.mViewHeight); this.mPerTextHeight = (this.mViewHeight / this.mSectionIndexerText.length); } @Override public boolean onTouchEvent(MotionEvent motionEvent) { boolean returnvalue = false; switch (motionEvent.getAction()) { case MotionEvent.ACTION_DOWN: if (DEBUG) { Log.d(TAG, "action down!"); } mListview.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_CANCEL, 0, 0, 0)); returnvalue = processTouchEvent(motionEvent); break; case MotionEvent.ACTION_MOVE: if (DEBUG) { Log.d(TAG, "action move!"); } returnvalue = processTouchEvent(motionEvent); break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: if (DEBUG) { Log.d(TAG, "action up!"); } setPressed(false); mView.setText(""); mView.setVisibility(View.GONE); returnvalue = true; break; default: break; } invalidate(); return returnvalue; } /** * 处理onTouch事件 * * @param motionEvent * MotionEvent * @return true 处理了触摸事件。false没有处理 */ private boolean processTouchEvent(MotionEvent motionEvent) { String selcected = ""; int backgroundPointX = this.mViewWidth - getPaddingRight() - mCharwidth * 3// SUPPRESS CHECKSTYLE - getPaddingLeft(); if (motionEvent.getX() < backgroundPointX) { mView.setVisibility(View.GONE); setPressed(false); return false; } setPressed(true); int curruntSection = (int) (motionEvent.getY() / this.mPerTextHeight); if (curruntSection >= 0 && curruntSection <= mSectionIndexerText.length - 1) { selcected = mSectionIndexerText[curruntSection]; mView.setVisibility(View.VISIBLE); } else { if (curruntSection < 0) { selcected = mSectionIndexerText[0]; } else if (curruntSection > mSectionIndexerText.length) { selcected = mSectionIndexerText[mSectionIndexerText.length - 1]; } mView.setVisibility(View.GONE); } boolean foundedPosition = false; for (int i = 0; i < mIndexer.getSections().length; i++) { SectionTitle title = (SectionTitle)mIndexer.getSections()[i]; if (selcected.equals(title.title)) { mListview.setSelection(mIndexer.getPositionForSection(i)); foundedPosition = true; break; } } if (foundedPosition) { mView.setBackgroundResource(R.drawable.section_text_bg); mView.setText(selcected); } else { mView.setBackgroundResource(R.drawable.section_text_gray_bg); mView.setText(selcected); } return true; } @Override public void setPressed(boolean pressed) { this.mIsPressed = pressed; } }
这样来初始化:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.contacts_list_content); mEmtytext = (TextView) findViewById(R.id.emptyListText); mLoadingBar = (ProgressBar) findViewById(R.id.loading); mQueryHandler = new MyHandler(this); mAdapter = new ContactsAdapter(this); mSectionIndexer = (SectionIndexerView)findViewById(R.id.section_indexer_view); TextView textView = (TextView)findViewById(R.id.section_text); getListView().setOnScrollListener(mAdapter); setListAdapter(mAdapter); <strong>mSectionIndexer.init(getListView(), mAdapter, textView);</strong> startQuery(); }
代码:http://download.csdn.net/detail/baidu_nod/7810525