zoukankan      html  css  js  c++  java
  • android系统联系人分组特效实现(1)---分组导航和挤压动画


    1.打开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"
        tools:context=".MainActivity" >
        <ListView 
            android:id="@+id/lv"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            ></ListView>
        <LinearLayout 
            android:layout_width="fill_parent"
            android:layout_height="18dp"
            android:id="@+id/title_layout"
            android:background="#303030"
            android:orientation="vertical"
            >
            <TextView 
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/title"
                android:textColor="#ffffff"
                />
        </LinearLayout>
    </RelativeLayout> 
    布局文件很简单,一个用来展示联系人信息的ListView,还有一个LinearLayout,里面有一个TextView,它的作用是在头部始终显示一个当前分组.

    2.新建item.xml布局,用于展示ListView的子项布局
    <?xml version="1.0" encoding="utf-8"?>
    <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:layout_width="fill_parent"
            android:layout_height="18dp"
            android:orientation="vertical"
            android:background="#303030"
            android:id="@+id/sort_key_layout"
            >
            <TextView 
                android:id="@+id/sort_key"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:gravity="center_horizontal"
                android:textColor="#ffffff"
                android:textSize="13sp"
                />
        </LinearLayout>
        
        <LinearLayout 
            android:layout_width="fill_parent"
            android:layout_height="50dp"
            android:orientation="horizontal"
            android:id="@+id/name_layout"
            >
            <ImageView 
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:src="@drawable/icon"
                />
            <TextView 
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/name"
                />
        </LinearLayout>
    </LinearLayout>
    在这个布局文件中,首先是放入了一个和前面完成一样的分组布局,因为不仅界面头部需要展示分组,在每个分组内的第一个无素之前都需要展示分组布局。然后是加入一个简单的LinearLayout,里面包含了一个ImageView用于显示联系人头像,还包含一个TextView用于显示联系人姓名。

    3.新建一个Contact.java,作为实体类
    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) {
            SortKey = sortKey;
        }
    } 

    4.接下来就是联系人列表适配器
    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;
        }
        
        @Override
        public 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 linearKeyLayout=(LinearLayout) layout.findViewById(R.id.sort_key_layout);
            TextView sortKey=(TextView) layout.findViewById(R.id.sort_key);
            name.setText(contact.getName());
            int section=mIndexer.getSectionForPosition(position);
            if(position==mIndexer.getPositionForSection(section)){
                sortKey.setText(contact.getSortKey());
                linearKeyLayout.setVisibility(View.VISIBLE);
            }
            else{
                linearKeyLayout.setVisibility(View.GONE);
            }
            return layout;
        }
        
        public void setIndexer(SectionIndexer mIndexer){
            this.mIndexer=mIndexer;
        }
    } 
    与往常不同的是,这个适配器不仅要排列联系人信息,还需要加上一个判断是否显示或隐藏当前分组信息.

    5.打开MainActivity.java
    public class MainActivity extends Activity {
        //分组的布局
        private LinearLayout titleLayout;
        //分组上显示的字母
        private TextView title;
        //联系人ListView
        private ListView contactListView;
        //适配器
        private ContactAdapter mAdapter;
        //用于字母进行分组
        private AlphabetIndexer indexer;
        //存储卡中所有的联系人
        private List<Contact> contactList=new ArrayList<Contact>();
        //定义字母的排序规则
        private String alphabet = "#ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        
        //上次第一个可见元素
        private int lastFirstVisibleItem=-1;
        
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            mAdapter=new ContactAdapter(this, R.layout.itemcontactList);
            titleLayout=(LinearLayout) findViewById(R.id.title_layout);
            title=(TextView) findViewById(R.id.title);
            contactListView=(ListView) findViewById(R.id.lv);
            
            Uri uri=ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
            Cursor cursor = getContentResolver().query(uri,
                    new String[] { "display_name""sort_key" }, nullnull"sort_key");
            if(cursor.moveToFirst()){
                do {
                    String name=cursor.getString(0);
                    String sort_name=getSortKey(cursor.getString(1));
                    Contact contact=new Contact();
                    contact.setName(name);
                    contact.setSortKey(sort_name);
                    contactList.add(contact);
                } while (cursor.moveToNext());
            }
            startManagingCursor(cursor);
            indexer=new AlphabetIndexer(cursor, 1, alphabet);
            mAdapter.setIndexer(indexer);
            if (contactList.size()>0) {
                setupContactListView();
            }
        }
        
        //为联系人ListView设置监听
        private void setupContactListView(){
            contactListView.setAdapter(mAdapter);
            contactListView.setOnScrollListener(new OnScrollListener() {
                @Override
                public void onScrollStateChanged(AbsListView arg0, int arg1) {
                    
                }
                
                @Override
                public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                    int section =indexer.getSectionForPosition(firstVisibleItem);
                    int nextSectionPosition=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(nextSectionPosition==firstVisibleItem+1){
                        View viewChild=view.getChildAt(0);
                        if(viewChild!=null){
                            int titleHeight=titleLayout.getHeight();
                            int bottom=viewChild.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;
                }
            });
        }
        
        /**
         * 获取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 "#";
        }
    }

     




    qq3061280@163.com
  • 相关阅读:
    JAVA中HashMap相关知识的总结(一)
    linux进阶之路(三):vi/vim编辑器
    linux进阶之路(二):linux文件目录
    linux进阶之路(一):linux入门
    linux:lrzsz安装
    一:阿里云服务器使用及后台环境搭建
    第二篇:线程七种状态
    Git log
    redis3.0 集群实战3
    详解Linux chgrp和chown命令的用法
  • 原文地址:https://www.cnblogs.com/aibuli/p/b582b2a1d9f4b4b3f5d1b69cbb7ecb79.html
Copyright © 2011-2022 走看看