Android 字母侧栏索引菜单

最近在做选择城市的列表,需要用到那个字母索引的,觉得这个东西不难就想偷偷懒百度算了,后来找了好几个都感觉写的太复杂了,想想还行自己写一个简单一点的算了,于是就有了下面的字母侧栏索引菜单控件了。

我写的这个很简单,基本都是LinearLayout和TextView,反正就是简单的不能再简单了

有两部分,一个是侧栏控件SidebarView,一个是侧栏子控件SidebarItemView

效果图:



SideBarItemView控件代码:

public class SidebarItemView extends LinearLayout {
    private Context mContext;
    private LinearLayout vLayout;
    private TextView vTitle;
    private int screenWidth;

    public SidebarItemView(Context context) {
        this(context, null, 0);
    }

    public SidebarItemView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public SidebarItemView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    private void init(Context context) {
        mContext = context;
        LayoutInflater.from(mContext).inflate(R.layout.wg_sidebar_item, this);
        vLayout = (LinearLayout) findViewById(R.id.wg_sidebar_item_root);
        vTitle = (TextView) findViewById(R.id.wg_sidebar_item_title);
        screenWidth = getScreenWidth();
        LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(screenWidth / 4, LayoutParams.WRAP_CONTENT);
        vLayout.setLayoutParams(lp);
    }

    /**
     * 获取屏幕的宽度(单位:px)
     *
     * @return 屏幕宽px
     */
    public int getScreenWidth() {
        WindowManager windowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics dm = new DisplayMetrics();// 创建了一张白纸
        windowManager.getDefaultDisplay().getMetrics(dm);// 给白纸设置宽高
        return dm.widthPixels;
    }

    /**
     * 设置值
     *
     * @param text
     */
    public void setText(String text) {
        vTitle.setText(text);
    }

    /**
     * 设置动画
     */
    public void setItemAnimation() {
        setAnimation(-(screenWidth / 12), -(screenWidth / 12));
    }

    /**
     * 设置动画
     */
    public void setItemAnimation2() {
        setAnimation(-(screenWidth / 22), -(screenWidth / 22));
    }

    /**
     * 设置动画
     * @param fromXDelta
     * @param toXDelta
     */
    private void setAnimation(float fromXDelta, float toXDelta) {
        AnimationSet animationSet = new AnimationSet(true);
        final TranslateAnimation animation = new TranslateAnimation(fromXDelta, toXDelta, 0, 0);
        animation.setDuration(50);//设置动画持续时间
        animation.setFillAfter(false);//动画结束后是否回到原位
        animationSet.addAnimation(animation);
        vTitle.startAnimation(animation);
        animation.startNow();
    }
}

SideBarItemView控件布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/wg_sidebar_item_root"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <TextView
        android:id="@+id/wg_sidebar_item_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="-"
        android:gravity="center"
        android:textColor="#666"
        android:layout_gravity="right"
        android:layout_marginRight="@dimen/space_8"
        android:padding="@dimen/space_4"
        android:textSize="@dimen/font_size_22px" />
</LinearLayout>

SidebarView控件代码:

public class SidebarView extends LinearLayout implements View.OnTouchListener {
    private Context mContext;
    private LinearLayout vLayout;
    private TextView vTitle;

    public SidebarView(Context context) {
        this(context, null, 0);
    }

    public SidebarView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public SidebarView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    private void init(Context context) {
        mContext = context;
        LayoutInflater.from(mContext).inflate(R.layout.wg_sidebar, this);
        vLayout = (LinearLayout) findViewById(R.id.wg_sidebar_layout);
        vTitle = (TextView) findViewById(R.id.wg_sidebar_title);

        vLayout.setOnTouchListener(this);
        List<String> listData = new ArrayList<>();
        listData.add("A");
        listData.add("B");
        listData.add("C");
        listData.add("D");
        listData.add("E");
        listData.add("F");
        listData.add("G");
        listData.add("H");
        listData.add("I");
        listData.add("J");
        listData.add("K");
        listData.add("L");
        listData.add("M");
        listData.add("N");
        listData.add("O");
        listData.add("P");
        listData.add("Q");
        listData.add("R");
        listData.add("S");
        listData.add("T");
        listData.add("U");
        listData.add("V");
        listData.add("W");
        listData.add("X");
        listData.add("Y");
        listData.add("Z");
        setSideDae(listData);
    }

    /**
     * 设置侧栏数据
     *
     * @param listData
     */
    public void setSideDae(List<String> listData) {
        vLayout.removeAllViews();
        for (String str : listData) {
            SidebarItemView tv = new SidebarItemView(mContext);
            tv.setTag(str);
            tv.setText(str);
            vLayout.addView(tv);
        }
    }

    private boolean isDown = false;

    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
            isDown = true;
        } else if (motionEvent.getAction() == MotionEvent.ACTION_UP || motionEvent.getAction() == MotionEvent.ACTION_CANCEL) {
            vTitle.setVisibility(View.GONE);
            isDown = false;
        }
        transformValue((LinearLayout) view, motionEvent);
        return true;
    }

    /**
     * 转换获取值
     *
     * @param layout
     * @param motionEvent
     */
    private void transformValue(LinearLayout layout, MotionEvent motionEvent) {
        SidebarItemView textView = (SidebarItemView) layout.getChildAt(0);
        float fistViewTop = textView.getTop();
        float itemHeight = textView.getMeasuredHeight();
        float currentY = motionEvent.getY();
        //不超过顶部和顶部
        if (motionEvent.getY() > 0 && motionEvent.getY() < layout.getMeasuredHeight()) {
            //不超过子控件的范围值
            if (currentY > fistViewTop && currentY < (fistViewTop + itemHeight * layout.getChildCount())) {
                float rang = currentY - fistViewTop;
                int index = (int) (rang / itemHeight);
                Log.e("kawa", "rang:" + rang + "_index:" + index + "_itemHeight:" + itemHeight);
                vTitle.setText((String) (layout.getChildAt(index).getTag()));
                if (listener!=null){
                    listener.onSelectItem(index,(String) (layout.getChildAt(index).getTag()));
                }
                if (isDown) {
                    vTitle.setVisibility(View.VISIBLE);
                    setAnimation(index, layout);
                }
            }
        }
    }

    /**
     * 设置动画
     *
     * @param index
     * @param layout
     */
    private void setAnimation(int index, LinearLayout layout) {
        if (index > 1 && index < layout.getChildCount() - 2) {
            SidebarItemView tv1 = (SidebarItemView) layout.getChildAt(index - 1);
            SidebarItemView tv2 = (SidebarItemView) layout.getChildAt(index);
            SidebarItemView tv3 = (SidebarItemView) layout.getChildAt(index + 1);
            tv1.setItemAnimation2();
            tv2.setItemAnimation();
            tv3.setItemAnimation2();
        } else {
            //第一个的
            if (index == 0) {
                SidebarItemView tv1 = (SidebarItemView) layout.getChildAt(index);
                SidebarItemView tv2 = (SidebarItemView) layout.getChildAt(index + 1);
                tv1.setItemAnimation();
                tv2.setItemAnimation2();
            }
            //最后一个的
            else {
                SidebarItemView tv1 = (SidebarItemView) layout.getChildAt(index);
                SidebarItemView tv2 = (SidebarItemView) layout.getChildAt(index - 1);
                tv1.setItemAnimation();
                tv2.setItemAnimation2();
            }
        }
    }

    private OnSidebarViewListener listener;

    public void setOnSidebarViewListener(OnSidebarViewListener l) {
        listener = l;
    }

    public interface OnSidebarViewListener {
        void onSelectItem(int index, String value);
    }
}


SidebarView控件布局文件:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="#ffffff"
    android:orientation="vertical">

    <LinearLayout
        android:id="@+id/wg_sidebar_layout"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_alignParentRight="true"
        android:gravity="center"
        android:orientation="vertical">

    </LinearLayout>

    <TextView
        android:id="@+id/wg_sidebar_title"
        android:layout_width="@dimen/space_120"
        android:layout_height="@dimen/space_120"
        android:layout_centerInParent="true"
        android:gravity="center"
        android:text="-"
        android:textSize="@dimen/font_size_30px"
        android:textColor="#fff"
        android:visibility="gone"
        android:background="#666"
        android:padding="@dimen/space_24"/>
</RelativeLayout>

用法,将你的控件引入到需要的页面就行

 <com.kawa.qkplug.widget.SidebarView
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

上面只是粗略写了一下,具体样式自己根据实际情况改改就行了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值