微信的通讯录首字母滑动的实现

国际规矩,关门,放截图

image                        image

左边是我写的,右边是微信的,功能差不多了

先讲使用到的东西

列表使用的是ExpandableListView,上面的字母就是Group来的

SideBar 的实现是使用了一个View,ABCD的排布是第一次初始化的时候使用Cavans画上去的

小方块就是一个在列表上面的TextView

具体情况,请看代码

Side.java

package auggie.demo.sidebardemo.widget;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

import auggie.demo.sidebardemo.R;


/**
 * Created With Android Studio
 * User Auggie Liang
 * Date 13-9-3
 * Time 上午9:33
 * 仿微信通许录旁边的bar
 */
public class SideBar extends View {
    public static final String TAG = SideBar.class.getName();
    private String[] letters;
    private OnLetterTouchListener letterTouchListener;

    public SideBar(Context context) {
        super(context);
        init(context);
    }

    public SideBar(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public SideBar(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context);
    }

    public void init(Context context){

    }

    /**
     * 每一项的高度
     */
    private float itemHeight = -1;
    private Paint paint;
    private Bitmap letterBitmap;
    @Override
    protected void onDraw(Canvas canvas) {
        if(letters == null){
            return ;
        }
        if(itemHeight == -1){
            itemHeight = getHeight() /letters.length;
        }
        if(paint == null){
            //初始化画笔
            paint = new Paint();
            paint.setTextSize(itemHeight - 4);
            //字体颜色
            paint.setColor(getResources().getColor(R.color.white));
            paint.setFlags(Paint.ANTI_ALIAS_FLAG);

            //创建一张包含所有列表的图
            Canvas mCanvas = new Canvas();
            letterBitmap = Bitmap.createBitmap(getMeasuredWidth(), getMeasuredHeight(),
                    Bitmap.Config.ARGB_8888);
//            Log.v(TAG, "width,height" + getMeasuredWidth() + ":" + getMeasuredHeight());
            mCanvas.setBitmap(letterBitmap);
            float widthCenter = getMeasuredWidth() / 2.0F;
            //画字符上图片中
            for(int i = 0 ; i < letters.length; i ++){
                mCanvas.drawText(letters[i], widthCenter-paint.measureText(letters[i])/2,
                        itemHeight * i +itemHeight,paint);
            }
        }
        if(letterBitmap != null){//图片不为空就画图
            canvas.drawBitmap(letterBitmap,0,0,paint);
        }
        super.onDraw(canvas);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        super.onTouchEvent(event);
        if(letterTouchListener == null || letters == null){
            return false;
        }
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
            case MotionEvent.ACTION_MOVE:
                Log.v(TAG, "action down or move");
                int position = (int) (event.getY() / itemHeight + 1);
                if(position >= 0 && position < letters.length){
                    letterTouchListener.onLetterTouch(letters[position],position);
                }
                return true;
            case MotionEvent.ACTION_OUTSIDE:
            case MotionEvent.ACTION_UP:
                Log.v(TAG, "action up");
                letterTouchListener.onActionUp();
                return true;
        }
        return false;
    }

    /**
     * 设置显示在边栏上的字母
     * @param letters
     */
    public void setShowString(String[] letters){
        this.letters = letters;
    }

    /**
     * 设置点击某个字母的时候
     * @param listener
     */
    public void setOnLetterTouchListener (OnLetterTouchListener listener){
        this.letterTouchListener = listener;
    }

    public interface OnLetterTouchListener{

        /**
         * 某个字母被按下的时候
         * @param letter
         * @param position
         */
        public void onLetterTouch(String letter, int position);

        /**
         * 触控手指离开的时候
         */
        public void onActionUp();
    }
}

MainActivity.java

package auggie.demo.sidebardemo;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.HashMap;

import auggie.demo.sidebardemo.widget.SideBar;

public class MainActivity extends Activity {

    ExpandableListView expandableListView;
    TextView tViewShowLetter;
    private static String[] letters;
    private HashMap<String, ArrayList<String>> lettersDivider = new HashMap<String,
            ArrayList<String>>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //test data;
        letters = getResources().getStringArray(R.array.alphabet);
        //由于是演示就不是用真实数据了
        ArrayList<String> names = new ArrayList<String>();
        names.add("heheh");
        names.add("我了个");
        names.add("并不是我");
        names.add("呵呵");
        names.add("嘻嘻");
        names.add("啦啦");
        names.add("lel");
        names.add("lle");
        names.add("lele");
        names.add("hehe");
        for (String letter : letters) {
            lettersDivider.put(letter, names);
        }

        tViewShowLetter = (TextView) findViewById(R.id.tView_letter);
        expandableListView = (ExpandableListView) findViewById(R.id.expandableListView);
        expandableListView.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
            @Override
            public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
                return true;//屏蔽点击收缩事件
            }
        });
        expandableListView.setAdapter(new MyBaseAdapter());

        SideBar sideBar = ((SideBar) findViewById(R.id.side_bar));
        sideBar.setOnLetterTouchListener(new SideBar.OnLetterTouchListener() {
            @Override
            public void onLetterTouch(String letter, int position) {
                tViewShowLetter.setVisibility(View.VISIBLE);
                tViewShowLetter.setText(letter);
                expandableListView.setSelectedGroup(position);
            }

            @Override
            public void onActionUp() {
                tViewShowLetter.setVisibility(View.GONE);
            }
        });
        sideBar.setShowString(letters);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }


    class MyBaseAdapter extends BaseExpandableListAdapter {

        @Override
        public int getGroupCount() {
            return letters.length;
        }

        @Override
        public int getChildrenCount(int groupPosition) {
            return lettersDivider.get(letters[groupPosition]).size();
        }

        @Override
        public Object getGroup(int groupPosition) {
            return null;
        }

        @Override
        public Object getChild(int groupPosition, int childPosition) {
            return null;
        }

        @Override
        public long getGroupId(int groupPosition) {
            return 0;
        }

        @Override
        public long getChildId(int groupPosition, int childPosition) {
            return 0;
        }

        @Override
        public boolean hasStableIds() {
            return false;
        }

        @Override
        public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
            if (!isExpanded) {
                expandableListView.expandGroup(groupPosition);//展开组
            }
            if (convertView == null) {
                convertView = View.inflate(MainActivity.this, R.layout.adapter_group_view, null);
                convertView.setTag(new GroupViewHolder(convertView));
            }
            GroupViewHolder holder = (GroupViewHolder) convertView.getTag();
            holder.tViewGroupName.setText(letters[groupPosition]);
            return convertView;
        }

        @Override
        public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
            if (convertView == null) {
                convertView = View.inflate(MainActivity.this, R.layout.adapter_child_view, null);
                convertView.setTag(new ChildViewHolder(convertView));
            }
            ChildViewHolder holder = (ChildViewHolder) convertView.getTag();
            holder.tViewChildName.setText(lettersDivider.get(letters[groupPosition]).get(childPosition));
            return convertView;
        }

        @Override
        public boolean isChildSelectable(int groupPosition, int childPosition) {
            return false;
        }

        class GroupViewHolder {
            TextView tViewGroupName;

            public GroupViewHolder(View parent) {
                tViewGroupName = (TextView) parent.findViewById(R.id.tView_group_name);
            }
        }

        class ChildViewHolder {
            TextView tViewChildName;

            public ChildViewHolder(View parent) {
                tViewChildName = (TextView) parent.findViewById(R.id.tView_child_name);
            }
        }
    }


}

主布局acivity_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:paddingLeft="@dimen/activity_horizontal_margin"
                android:paddingRight="@dimen/activity_horizontal_margin"
                android:paddingTop="@dimen/activity_vertical_margin"
                android:paddingBottom="@dimen/activity_vertical_margin"
                tools:context=".MainActivity">

    <ExpandableListView
            android:layout_height="match_parent"
            android:layout_width="match_parent"
            android:groupIndicator="@null"
            android:id="@+id/expandableListView"/>

    <auggie.demo.sidebardemo.widget.SideBar
            android:id="@+id/side_bar"
            android:layout_alignParentRight="true"
            android:background="@color/black"
            android:layout_width="14dp"
            android:layout_height="match_parent"/>

    <TextView
            android:id="@+id/tView_letter"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:textSize="35sp"
            android:visibility="gone"
            android:gravity="center"
            tools:text="A"
            android:textColor="@color/white"
            android:background="@color/blue"
            android:layout_centerInParent="true"/>
</RelativeLayout>
posted @ 2013-10-12 15:18  hangox  阅读(1878)  评论(4编辑  收藏  举报