Android系统联系人全特效实现(下),字母表快速滚动

private void setAlpabetListener() {
alphabetButton.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
float alphabetHeight = alphabetButton.getHeight();
float y = event.getY();
int sectionPosition = (int) ((y / alphabetHeight) / (1f / 27f));
if (sectionPosition < 0) {
sectionPosition = 0;
} else if (sectionPosition > 26) {
sectionPosition = 26;
}
String sectionLetter = String.valueOf(alphabet.charAt(sectionPosition));
int position = indexer.getPositionForSection(sectionPosition);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
alphabetButton.setBackgroundResource(R.drawable.a_z_click);
sectionToastLayout.setVisibility(View.VISIBLE);
sectionToastText.setText(sectionLetter);
contactsListView.setSelection(position);
break;
case MotionEvent.ACTION_MOVE:
sectionToastText.setText(sectionLetter);
contactsListView.setSelection(position);
break;
default:
alphabetButton.setBackgroundResource(R.drawable.a_z);
sectionToastLayout.setVisibility(View.GONE);
}
return true;
}
});
}

可以看到,在这个方法中我们注册了字母表按钮的 onTouch 事件,然后在 onTouch 方法里做了一些逻辑判断和处理,下面我来一一详细说明。首先通过字母表按钮的 getHeight 方法获取到字母表的总高度,然后用 event.getY 方法获取到目前手指在字母表上的纵坐标,用纵坐标除以总高度就可以得到一个用小数表示的当前手指所在位置 (0 表在 #端,1 表示在 Z 端)。由于我们的字母表中一共有 27 个字符,再用刚刚算出的小数再除以 1/27 就可以得到一个 0 到 27 范围内的浮点数,之后再把这个浮点数向下取整,就可以算出我们当前按在哪个字母上了。然后再对 event 的 action 进行判断,如果是 ACTION_DOWN 或 ACTION_MOVE,就在弹出式分组上显示当前手指所按的字母,并调用 ListView 的 setSelection 方法把列表滚动到相应的分组。如果是其它的 action,就将弹出式分组布局隐藏。

MainActivity 的完整代码如下:

public class MainActivity extends Activity {

/**

  • 分组的布局
    */
    private LinearLayout titleLayout;

/**

  • 弹出式分组的布局
    */
    private RelativeLayout sectionToastLayout;

/**

  • 右侧可滑动字母表
    */
    private Button alphabetButton;

/**

  • 分组上显示的字母
    */
    private TextView title;

/**

  • 弹出式分组上的文字
    */
    private TextView sectionToastText;

/**

  • 联系人ListView
    */
    private ListView contactsListView;

/**

  • 联系人列表适配器
    */
    private ContactAdapter adapter;

/**

  • 用于进行字母表分组
    */
    private AlphabetIndexer indexer;

/**

  • 存储所有手机中的联系人
    */
    private List contacts = new ArrayList();

/**

  • 定义字母表的排序规则
    */
    private String alphabet = “#ABCDEFGHIJKLMNOPQRSTUVWXYZ”;

/**

  • 上次第一个可见元素,用于滚动时记录标识。
    */
    private int lastFirstVisibleItem = -1;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
adapter = new ContactAdapter(this, R.layout.contact_item, contacts);
titleLayout = (LinearLayout) findViewById(R.id.title_layout);
sectionToastLayout = (RelativeLayout) findViewById(R.id.section_toast_layout);
title = (TextView) findViewById(R.id.title);
sectionToastText = (TextView) findViewById(R.id.section_toast_text);
alphabetButton = (Button) findViewById(R.id.alphabetButton);
contactsListView = (ListView) findViewById(R.id.contacts_list_view);
Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
Cursor cursor = getContentResolver().query(uri,
new String[] { “display_name”, “sort_key” }, null, null, “sort_key”);
if (cursor.moveToFirst()) {
do {
String name = cursor.getString(0);
String sortKey = getSortKey(cursor.getString(1));
Contact contact = new Contact();
contact.setName(name);
contact.setSortKey(sortKey);
contacts.add(contact);
} while (cursor.moveToNext());
}
startManagingCursor(cursor);
indexer = new AlphabetIndexer(cursor, 1, alphabet);
adapter.setIndexer(indexer);
if (contacts.size() > 0) {
setupContactsListView();
setAlpabetListener();
}
}

/**

  • 为联系人ListView设置监听事件,根据当前的滑动状态来改变分组的显示位置,从而实现挤压动画的效果。
    */
    private void setupContactsListView() {
    contactsListView.setAdapter(adapter);
    contactsListView.setOnScrollListener(new OnScrollListener() {
    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
    }

@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
int totalItemCount) {
int section = indexer.getSectionForPosition(firstVisibleItem);
int nextSecPosition = indexer.getPositionForSection(section + 1);
if (firstVisibleItem != lastFirstVisibleItem) {
MarginLayoutParams params = (MarginLayoutParams) titleLayout.getLayoutParams();
params.topMargin = 0;
titleLayout.setLayoutParams(params);
title.setText(String.valueOf(alphabet.charAt(section)));
}
if (nextSecPosition == firstVisibleItem + 1) {
View childView = view.getChildAt(0);
if (childView != null) {
int titleHeight = titleLayout.getHeight();
int bottom = childView.getBottom();
MarginLayoutParams params = (MarginLayoutParams) titleLayout
.getLayoutParams();
if (bottom < titleHeight) {
float pushedDistance = bottom - titleHeight;
params.topMargin = (int) pushedDistance;
titleLayout.setLayoutParams(params);
} else {
if (params.topMargin != 0) {
params.topMargin = 0;
titleLayout.setLayoutParams(params);
}
}
}
}
lastFirstVisibleItem = firstVisibleItem;
}
});

}

/**

  • 设置字母表上的触摸事件,根据当前触摸的位置结合字母表的高度,计算出当前触摸在哪个字母上。
  • 当手指按在字母表上时,展示弹出式分组。手指离开字母表时,将弹出式分组隐藏。
    */
    private void setAlpabetListener() {
    alphabetButton.setOnTouchListener(new OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
    float alphabetHeight = alphabetButton.getHeight();
    float y = event.getY();
    int sectionPosition = (int) ((y / alphabetHeight) / (1f / 27f));
    if (sectionPosition < 0) {
    sectionPosition = 0;
    } else if (sectionPosition > 26) {
    sectionPosition = 26;
    }

最后

今天关于面试的分享就到这里,还是那句话,有些东西你不仅要懂,而且要能够很好地表达出来,能够让面试官认可你的理解,例如Handler机制,这个是面试必问之题。有些晦涩的点,或许它只活在面试当中,实际工作当中你压根不会用到它,但是你要知道它是什么东西。

最后在这里小编分享一份自己收录整理上述技术体系图相关的几十套腾讯、头条、阿里、美团等公司2021年的面试题,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分。

还有 高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料 帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。

【算法合集】

【延伸Android必备知识点】

【Android部分高级架构视频学习资源】

**Android精讲视频领取学习后更加是如虎添翼!**进军BATJ大厂等(备战)!现在都说互联网寒冬,其实无非就是你上错了车,且穿的少(技能),要是你上对车,自身技术能力够强,公司换掉的代价大,怎么可能会被裁掉,都是淘汰末端的业务Curd而已!现如今市场上初级程序员泛滥,这套教程针对Android开发工程师1-6年的人员、正处于瓶颈期,想要年后突破自己涨薪的,进阶Android中高级、架构师对你更是如鱼得水,赶快领取吧!

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 30
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值