假设给Contact的List加一个用字母排序的导航
效果图:
这样写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();
}
假设给Contact的List加一个用字母排序的导航的更多相关文章
- WordPress制作一个首字母排序的标签页面
很早就想制作这样一个页面了,废话不多说, 先看看效果:传送门 在网上找了很多的代码,试了很久,修改了一些代码,最终就达到了现在的效果. 实现方法:(里面增加了缓存功能,打开页面更快,对数据进行了缓存, ...
- C++在字符串前加一个L作用:
在字符串前加一个L作用: 如 L"我的字符串" 表示将ANSI字符串转换成unicode的字符串,就是每个字符占用两个字节. strlen("asd" ...
- oracle 中的trunc()函数及加一个月,一天,一小时,一分钟,一秒钟方法
返回处理后的数据,不同于round()(对数值进行四舍五入处理),该函数不对指定小数前或后的数值部分进行舍入处理. 语法:trunc(number[,decimals]) 其中,number为待做处理 ...
- iOS圆形图片裁剪,以及原型图片外面加一个圆环
废话不多说,直接上代码 #import "ViewController.h" @interface ViewController () @property (nonatomic,s ...
- 如何给div加一个边框border样式
如何给div加一个边框样式? 对div盒子加一个边框样式很简单只需要使用border板块样式即可. 一.虚线与实线边框 边框虚线样式:dashed 边框实现样式:solid border:1px da ...
- sh里没有多行注释,只能每一行加一个#号
sh里没有多行注释,只能每一行加一个#号.只能像这样: #-------------------------------------------- # 这是一个自动打ipa的脚本,基于webfrogs ...
- express4.0之后不会解析req.files,必须加一个插件multer
express 4 + 用multer express4.0之后不会解析req.files,必须加一个插件multer http://www.w3school.com.cn/tags/att_form ...
- iOS 给UITextView加一个placeholder
苹果并没有为UITextView提供placeholder功能.我们可以通过两种办法实现. 方法一: 思路:设置默认显示的文字,颜色设置为灰色.代理方法监听textView点击. 缺点:如果点击到文字 ...
- [UE4]快速移动,给单位向量加一个力
一.(Vector_End- Vector_Start ).Normalize,获取从起始位置指向目标位置的单位向量. 二.给单位向量乘以一个浮点数,即给向量加一个力,是往向量方向移动 每一帧往目标点 ...
随机推荐
- hdu 2828 Lamp 重复覆盖
题目链接 给n个灯和m个开关, 每个灯可以由若干个开关控制, 每个开关也可以控制若干个灯, 问你能否找到一种开关的状态, 使得所有的灯都亮. 将灯作为列, 然后把每个开关拆成两行, 开是一行, 关是一 ...
- c语言:从一组数据中选出可以组成三角形并且周长最长的三个数(简单)
题目如下: 思路分析: 写出完整的程序: /* 问题描述: 有n根棍子,棍子i的长度为ai.想要从中选出3根棍子组成周长尽可能长的三角形.请输 出最大的周长,若无法组成三角形则输出0. */ #inc ...
- [原创]linux简单之美(三)
原文链接:linux简单之美(三) 在linux简单之美(二)中我们尝试使用了C库的函数完成功能,那么能不能用syscall方式来搞呢?显然可以! section .data ft db sectio ...
- 编程工具篇——Vim
配置 配置文件位于:/etc/vim/vimrc(添加配置在文件末尾输入代码即可) 常用配置 配色方案 :colorscheme ron(其中ron为我的配色方案,也可以选择其他,软件中自带配色文件全 ...
- Java定时器:Timer
项目中往往会遇到需要定时的任务,例如订单,当用户在某个规定时间内没有操作订单时,订单状态将会发生改变. 那么在这种情况下,我们会用到定时器. 举例: import java.util.Timer; / ...
- Oracle EBS-SQL (AR-2):检查应收收款核销额
SELECT cust.customer_number, cust.customer_name, cash.receipt_number, gcc.segment1 || '.' ...
- 传智播客C/C++学院年薪24-50万招聘C/C++讲师
C/C++技术讲师 6名 (北京,年薪:24-50万) 传智播客C/C++课程培训体系如下: 1.C语言,世界五百强C语言面试训练 2.C++语言,世界五百强C++语言面试训练 3.数据结构与算法,世 ...
- 【Deep Learning】genCNN: A Convolutional Architecture for Word Sequence Prediction
作者:Mingxuan Wang.李航,刘群 单位:华为.中科院 时间:2015 发表于:acl 2015 文章下载:http://pan.baidu.com/s/1bnBBVuJ 主要内容: 用de ...
- Objective-C内存管理教程和原理剖析(三)
初学Objective-C的朋友都有一个困惑,总觉得对Objective-C的内存管理机制琢磨不透,程 序经常内存泄漏或莫名其妙的崩溃.我在这里总结了自己对Objective-C内存管理机制的研究成果 ...
- Heritrix个性化设置抓取目标
本文是Heritrix的使用的高级篇,针对对Heritrix已经能够运行的码农朋友们! 我们在抓取网页的时候,网页的链接中往往会包含有js.css.图片.视频等文件,第一次执行抓取任务的时候,许多农民 ...