ListView分组导航+挤压动画(一)
来源:互联网 发布:苹果动态壁纸软件 编辑:程序博客网 时间:2024/04/28 00:57
感谢郭神,转自郭神
——————————————————————————————————————————
首先来看下面这个表格,这是一个排序好的list,Position是唯一,就像ID一样; List是排序的数据;Section是分组的号
那么现在就以上面这个表做依据来看上面两个方法具体的实现:
getPositionForSection:
getPositionForSection(int sectionIndex):参数为0,返回的结果为0
getPositionForSection(int sectionIndex):参数为1,返回的结果为3
getPositionForSection(int sectionIndex):参数为2,返回的结果为5
getSectionForPosition:
getSectionForPosition(int position): 参数为0,返回的结果为0
getSectionForPosition(int position): 参数为1,返回的结果为0
getSectionForPosition(int position): 参数为3,返回的结果为1
getSectionForPosition(int position): 参数为5,返回的结果为2
利用以上两个方法就可以实现通信录进行分组
——————————————————————————————————activity_main.xml(主布局)
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <ListView android:id="@+id/contacts_list_view" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:fadingEdge="none" > </ListView> <LinearLayout android:id="@+id/title_layout" android:layout_width="fill_parent" android:layout_height="18dip" android:layout_alignParentTop="true" android:background="#303030" > <TextView android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:layout_marginLeft="10dip" android:textColor="#ffffff" android:textSize="13sp" /> </LinearLayout></RelativeLayout>
contact_item.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <LinearLayout android:id="@+id/sort_key_layout" android:layout_width="fill_parent" android:layout_height="18dip" android:background="#303030" > <TextView android:id="@+id/sort_key" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:layout_marginLeft="10dip" android:textColor="#ffffff" android:textSize="13sp" /> </LinearLayout> <LinearLayout android:id="@+id/name_layout" android:layout_width="fill_parent" android:layout_height="50dip" > <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_marginLeft="10dip" android:layout_marginRight="10dip" android:src="@drawable/icon" /> <TextView android:id="@+id/name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:textColor="#ffffff" android:textSize="22sp" /> </LinearLayout></LinearLayout>
Contact
package com.example.contactsdemo;/** * 联系人实体类 */public class Contact {/** * 联系人姓名 */private String name;/** * 排序字母 */private String sortKey;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getSortKey() {return sortKey;}public void setSortKey(String sortKey) {this.sortKey = sortKey;}}
MainActivity
package com.example.contactsdemo;import java.util.ArrayList;import java.util.List;import android.app.Activity;import android.database.Cursor;import android.net.Uri;import android.os.Bundle;import android.provider.ContactsContract;import android.view.View;import android.view.ViewGroup.MarginLayoutParams;import android.widget.AbsListView;import android.widget.AbsListView.OnScrollListener;import android.widget.AlphabetIndexer;import android.widget.LinearLayout;import android.widget.ListView;import android.widget.TextView;/** * 主界面,联系人列表界面。 */public class MainActivity extends Activity {/** 分组的布局*/private LinearLayout titleLayout;/**分组上显示的字母*/private TextView title;/** 联系人ListView*/private ListView contactsListView;/** 联系人列表适配器*/private ContactAdapter adapter;/** 用于进行字母表分组*/private AlphabetIndexer indexer;/**存储所有手机中的联系人*/private List<Contact> contacts = new ArrayList<Contact>();/**定义字母表的排序规则*/private String alphabet = "#ABCDEFGHIJKLMNOPQRSTUVWXYZ";/**上次第一个可见元素,用于滚动时记录标识。*/private int lastFirstVisibleItem = -1;/** * 在onCreate方法中,我们从系统联系人数据库中去查询联系人的姓名和排序键, * 之后将查询返回的cursor直接传入AlphabetIndexer作为第一个参数 * 。由于我们一共就查了两列,排序键在第二列,所以我们第二个sortedColumnIndex参数传入1 * 。第三个alphabet参数这里传入了"#ABCDEFGHIJKLMNOPQRSTUVWXYZ" * 字符串,因为可能有些联系人的姓名不在字母表范围内,我们统一用#来表示这部分联系人。 */@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);// 一个字母条线性布局、一个listView视图--它的作用是在界面头部始终显示一个当前分组。setContentView(R.layout.activity_main);// 适配器adapter = new ContactAdapter(this, R.layout.contact_item, contacts);// listView的上部分布局----它的作用是在界面头部始终显示一个当前分组。titleLayout = (LinearLayout) findViewById(R.id.title_layout);title = (TextView) findViewById(R.id.title);// listViewcontactsListView = (ListView) findViewById(R.id.contacts_list_view);// 获取系统联系人的url地址路径Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;// getContentResolver().query(uri, projection, selection, selectionArgs,// sortOrder)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());}// 将查询的结果的第二列通过字母表进行查询--字母索引辅助类indexer = new AlphabetIndexer(cursor, 1, alphabet);adapter.setIndexer(indexer);if (contacts.size() > 0) {setupContactsListView();}}/** * 为联系人ListView设置监听事件,根据当前的滑动状态来改变分组的显示位置,从而实现挤压动画的效果。 */private void setupContactsListView() {// 设置适配器contactsListView.setAdapter(adapter);contactsListView.setOnScrollListener(new OnScrollListener() {@Overridepublic void onScrollStateChanged(AbsListView view, int scrollState) {}@Overridepublic void onScroll(AbsListView view, int firstVisibleItem,int visibleItemCount, int totalItemCount) {// 获取listView可见条目的Section索引值int section = indexer.getSectionForPosition(firstVisibleItem);// 按指定section的索引值返回listView的postion索引值int nextSecPosition = indexer.getPositionForSection(section + 1);/** * 某个字母条索引里面的正常的每条item时候,字母条的布局形态 */if (firstVisibleItem != lastFirstVisibleItem) {MarginLayoutParams params = (MarginLayoutParams) titleLayout.getLayoutParams();params.topMargin = 0;titleLayout.setLayoutParams(params);title.setText(String.valueOf(alphabet.charAt(section)));}/** * 下个分组的第一个元素值等于第一个可见元素的值加1,那就说明下个分组的布局要和界面顶部分组布局相碰了 */if (nextSecPosition == firstVisibleItem + 1) {// 再通过ListView的getChildAt(0)方法,获取到界面上显示的第一个子ViewView childView = view.getChildAt(0);if (childView != null) {int titleHeight = titleLayout.getHeight();int bottom = childView.getBottom();MarginLayoutParams params = (MarginLayoutParams) titleLayout.getLayoutParams();if (bottom < titleHeight) {//就是listView头部的 字母条隐藏的高度负值~~~~~~~~~~~~float pushedDistance = bottom - titleHeight;params.topMargin = (int) pushedDistance;titleLayout.setLayoutParams(params);} else {if (params.topMargin != 0) {params.topMargin = 0;titleLayout.setLayoutParams(params);}}}}lastFirstVisibleItem = firstVisibleItem;}});}/** * 获取sort key的首个字符,如果是英文字母就直接返回,否则返回#。 * * @param sortKeyString * 数据库中读取出的sort key * @return 英文字母或者# */private String getSortKey(String sortKeyString) {String key = sortKeyString.substring(0, 1).toUpperCase();if (key.matches("[A-Z]")) {return key;}return "#";}}
ContactAdapter
package com.example.contactsdemo;import java.util.List;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.ArrayAdapter;import android.widget.LinearLayout;import android.widget.SectionIndexer;import android.widget.TextView;/** * 联系人列表适配器。 */public class ContactAdapter extends ArrayAdapter<Contact> {/** * 需要渲染的item布局文件 */private int resource;/** * 字母表分组工具 */private SectionIndexer mIndexer;public ContactAdapter(Context context, int textViewResourceId,List<Contact> objects) {super(context, textViewResourceId, objects);resource = textViewResourceId;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {Contact contact = getItem(position);LinearLayout layout = null;if (convertView == null) {layout = (LinearLayout) LayoutInflater.from(getContext()).inflate(resource, null);} else {layout = (LinearLayout) convertView;}TextView name = (TextView) layout.findViewById(R.id.name);//字母条布局LinearLayout sortKeyLayout = (LinearLayout) layout.findViewById(R.id.sort_key_layout);TextView sortKey = (TextView) layout.findViewById(R.id.sort_key);//设置值name.setText(contact.getName());//获取某个item的section值int section = mIndexer.getSectionForPosition(position);if (position == mIndexer.getPositionForSection(section)) {sortKey.setText(contact.getSortKey());sortKeyLayout.setVisibility(View.VISIBLE);} else {sortKeyLayout.setVisibility(View.GONE);}return layout;}/** * 给当前适配器传入一个分组工具。 */public void setIndexer(SectionIndexer indexer) {mIndexer = indexer;}}
0 0
- ListView分组导航+挤压动画(一)
- ListView分组导航+挤压动画(二)
- Android 通讯录分组导航和挤压动画
- Android ListView的A-Z字母排序、分组导航、挤压动画
- Android系统联系人全特效实现(上),分组导航和挤压动画
- Android系统联系人全特效实现(上),分组导航和挤压动画
- Android系统联系人全特效实现(上),分组导航和挤压动画
- Android系统联系人全特效实现(上),分组导航和挤压动画
- Android系统联系人全特效实现(上),分组导航和挤压动画
- Android系统联系人全特效实现(上),分组导航和挤压动画
- Android系统联系人全特效实现(上),分组导航和挤压动画
- Android系统联系人全特效实现(上),分组导航和挤压动画
- Android系统联系人全特效实现(上),分组导航和挤压动画
- Android系统联系人全特效实现(上),分组导航和挤压动画
- Android系统联系人全特效实现(上),分组导航和挤压动画
- Android系统联系人全特效实现(上),分组导航和挤压动画
- Android系统联系人全特效实现(上),分组导航和挤压动画
- Android系统联系人全特效实现(上),分组导航和挤压动画
- Qt入门学习——Qt Creator 中 ui 文件和 Qt 代码关系
- 我最喜欢开头这段话!!!
- LoadRunner录制模式之html-based和URL-based区别
- 浅拷贝与深拷贝
- Android音乐播放器 -- 滑动切换实现
- ListView分组导航+挤压动画(一)
- J版 OpenStack动态加载菜单图片详解
- Securing a Linux Server
- Java jsp 分页显示数据
- fragment lazy load problem
- LeetCode-Ugly Number
- mysql单表数量极限和性能
- ScrollView+Fragment+ListView嵌套ListView,麻麻再也不用担心我不会写嵌套
- iOS开发中,修改了Xcode里面的头文件的解决办法