• android系统联系人分组特效实现(2)---字母表快速滚动


    要实现这种功能,只需要在   android系统联系人分组特效实现(1)---分组导航和挤压动画  的基础上再加上一个自定义控件即可完成.
    1.新建项目,继续新建一个java类,BladeView,用于作为导航栏
    public class BladeView extends View {
        private Handler handler = new Handler();
        public BladeView(Context context, AttributeSet attrs) {
            super(context, attrs);
            TypedArray a=getContext().obtainStyledAttributes(attrs,R.styleable.NewMyElement);
            textSize=a.getDimension(R.styleable.NewMyElement_textSize, 15);
            a.recycle();
        }
        private PopupWindow mPopupWindow;
        private TextView mPopupText;
        float textSize;
        
        public interface OnMyImteClickListener{
            void onItemClick(int s);
        }
        private OnMyImteClickListener mListener;
        
        public void setOnMyItemClickListener(OnMyImteClickListener listener){
            this.mListener=listener;
        }
        
        String b[]={ "#""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" };
        int choose=-1;
        Paint paint=new Paint();
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            int height=getHeight();
            int width=getWidth();
            int singleHeight=height/b.length;
            for (int i = 0; i < b.length; i++) {
                paint.setTextSize(textSize);
                paint.setColor(Color.BLACK);
                if(i==choose){
                    paint.setColor(Color.BLUE);
                }
                float xPos=width/2-paint.measureText(b[i])/2;
                float yPos=singleHeight*i+singleHeight;
                canvas.drawText(b[i], xPos, yPos, paint);
                paint.reset();
            }
        }
        @Override
        public boolean dispatchTouchEvent(MotionEvent event) {
            float y=event.getY();
            int oldChoose=choose;
            int c=(int)(y/getHeight()*b.length);
            switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                if(oldChoose!=c){
                    if(c>=0&&c<b.length){
                        choose=c;
                        mListener.onItemClick(c);
                        showPopup(c);
                        invalidate();
                    }
                }
                break;
            case MotionEvent.ACTION_MOVE:
                if(oldChoose!=c){
                    if(c>=0&&c<b.length){
                        choose=c;
                        mListener.onItemClick(c);
                        showPopup(c);
                        invalidate();
                    }
                }
                break;
            case MotionEvent.ACTION_UP:
                choose=-1;
                mListener.onItemClick(-1);
                dismissPopup();
                invalidate();
                break;
            default:
                break;
            }
            return true;
        }
        private void showPopup(int item) {
            if (mPopupWindow == null) {
                handler.removeCallbacks(dismissRunnable);
                mPopupText = new TextView(getContext());
                mPopupText.setBackgroundColor(Color.GRAY);
                mPopupText.setTextColor(Color.CYAN);
                mPopupText.setTextSize(50);
                mPopupText.setGravity(Gravity.CENTER_HORIZONTAL
                        | Gravity.CENTER_VERTICAL);
                mPopupWindow = new PopupWindow(mPopupText, 100, 100);
            }
            String text = "";
            if (item == 0) {
                text = "#";
            } else {
                text = Character.toString((char) ('A' + item - 1));
            }
            mPopupText.setText(text);
            if (mPopupWindow.isShowing()) {
                mPopupWindow.update();
            } else {
                mPopupWindow.showAtLocation(getRootView(),
                        Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL, 0, 0);
            }
        }
        private void dismissPopup() {
            handler.postDelayed(dismissRunnable, 800);
        }
        Runnable dismissRunnable = new Runnable() {
            @Override
            public void run() {
                if (mPopupWindow != null) {
                    mPopupWindow.dismiss();
                }
            }
        };
    }

    2.打开activity_main.xml
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:my="http://schemas.android.com/apk/res/com.example.mycontact" 
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="com.example.mycontact.MainActivity" >
        <ListView 
            android:id="@+id/lv_contact"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:scrollbars="none"
            android:fadingEdge="none"
            ></ListView>
        
        <LinearLayout 
            android:id="@+id/title_layout"
            android:layout_width="fill_parent"
            android:layout_height="18dp"
            android:layout_alignParentTop="true"
            android:orientation="vertical"
            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="10dp"
                android:textColor="#ffffff"
                android:textSize="13sp"
                />
        </LinearLayout>
        <com.example.mycontact.BladeView 
            android:id="@+id/BladeView"
            android:layout_width="30dp"
            android:layout_height="fill_parent"
            android:layout_alignParentRight="true"
            my:textSize="23sp"
            />
        <RelativeLayout 
            android:id="@+id/section_toast_layout"
            android:layout_width="70dp"
            android:layout_height="70dp"
            android:layout_centerInParent="true"
            android:background="@drawable/section_toast"
            android:visibility="gone"
            >
            <TextView 
                android:id="@+id/section_toast_text"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true"
                android:textColor="#ffffff"
                android:textSize="30sp"
                />
        </RelativeLayout>
    </RelativeLayout> 

    3.实现主要功能之前,还需一个实体类
    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;
        }
    }

    4.还需要一个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:id="@+id/sort_key_layout"
            android:layout_width="fill_parent"
            android:layout_height="18dp"
            android:orientation="vertical"
            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="10dp"
                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: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>

    5.展示数据的适配器
    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(resourcenull);
            }
            else{
                layout=(LinearLayout) convertView;
            }
            TextView name=(TextView) layout.findViewById(R.id.name);
            LinearLayout sortKeyLayout=(LinearLayout) layout.findViewById(R.id.sort_key_layout);
            TextView sort_key=(TextView) layout.findViewById(R.id.sort_key);
            name.setText(contact.getName());
            int section=mIndexer.getSectionForPosition(position);
            if(position==mIndexer.getPositionForSection(section)){
                sortKeyLayout.setVisibility(View.VISIBLE);
                sort_key.setText(contact.getSortKey());
            }
            else{
                sortKeyLayout.setVisibility(View.GONE);
            }
            return layout;
        }
        
        //给当前适配器传入一个分组工具
        public void setIndexer(SectionIndexer indexer){
            mIndexer=indexer;
        }
    }

    6.最关键的MainActivity.java
    public class MainActivity extends ActionBarActivity {
        //分组的布局
        private LinearLayout titleLayout;
        //弹出式分组的布局
        private RelativeLayout sectionToastLayout;
        //右侧可滑动字母表
        private BladeView bView;
        //分组上显示的字母
        private TextView title;
        //弹出式分组上的文字
        private TextView sectionToastText;
        //联系人ListView
        private ListView contactListView;
        //联系人列表适配器
        private ContactAdapter adapter;
        //用于对字母表进行分组
        private AlphabetIndexer indexer;
        //存储手机中所有联系人
        private List<Contact> contactsList=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);
            adapter=new ContactAdapter(this, R.layout.item,contactsList);
            titleLayout=(LinearLayout) findViewById(R.id.title_layout);
            title=(TextView) findViewById(R.id.title);
            sectionToastLayout=(RelativeLayout) findViewById(R.id.section_toast_layout);
            sectionToastText=(TextView) findViewById(R.id.section_toast_text);
            bView=(BladeView) findViewById(R.id.BladeView);
            contactListView=(ListView) findViewById(R.id.lv_contact);
            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 sortKey=getSortKey(cursor.getString(1));
                    Contact contact=new Contact();
                    contact.setName(name);
                    contact.setSortKey(sortKey);
                    contactsList.add(contact);
                } while (cursor.moveToNext());
            }
            startManagingCursor(cursor);
            indexer=new AlphabetIndexer(cursor, 1, alphabet);
            adapter.setIndexer(indexer);
            if(contactsList.size()>0){
                setupContactListView();
                setAlphabetListener();
            }
        }
        //为联系人ListView设置滑动监听
        private void setupContactListView(){
            contactListView.setAdapter(adapter);
            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 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 setAlphabetListener(){
            bView.setOnMyItemClickListener(new OnMyImteClickListener() {
                @Override
                public void onItemClick(int s) {
                    if(s!=-1){
                        contactListView.setSelection(indexer.getPositionForSection(s));
                    }
                }
            });
        }
        
        //获取sort_key的首字母
        private String getSortKey(String sortKeyString){
            String key=sortKeyString.substring(0, 1).toUpperCase();
            if(key.matches("[A-Z]")){
                return key;
            }
            return "#";
        }
    }

     





    qq3061280@163.com
  • 相关阅读:
    c#读取INI文件
    无题
    tnsping 命令解析
    宁静——一种心灵的奢望
    .NET框架类别
    19任意三个数的和为15
    VS.NET2005安装过程中遇到error:1935错误时的解决方法
    SQL Server 2005 : 存储过程传递字符串类型参数时,如何在参数中包含单引号
    SQL Server 2005 : 分割字符串
    网站发布在中文操作系统,但ReportViewer的工具栏显示为英文的解决方法
  • 原文地址:https://www.cnblogs.com/aibuli/p/37735bc18e90b132e86dedf77d996994.html
Copyright © 2020-2023  润新知