【Android】自定义控件-仿QQ联系人侧滑条目,右侧滑菜单。

一直没有写博客的习惯,一直都是看别人的博客,学习别人的东西。平时工作中总会遇到或大或小的问题,往往是上百度CSDN查找答案。今天尝试着写博客,一是更加深入地熟悉一下博客;二是转变一下学习方式;三是把自己所学的东西分享出来,帮助别人的同时也提升了自己!

在写项目时经常会用到一些自定义控件,我把这些自定义控件整理分享出来,如果有同样需求的朋友可以直接拿去用,省时又省事!

这是一个实用的右侧滑控件,可以用于QQ联系人列表的侧滑条目,也可以用于酷狗的右侧滑菜单。根据不同的需求改变布局。

1、仿QQ侧滑按钮

这里写图片描述

  • 先看布局文件activity_listdemo.xml 里面就一个标题和ListView,主要是ListView中的条目item_slideslip.xml和item_slideslip2.xml
activity_listdemo.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#D0D0D0"
        android:gravity="center"
        android:padding="10dp">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="侧拉按钮"
            android:textColor="#FFF"
            android:textSize="20sp" />
    </LinearLayout>

    <ListView
        android:id="@+id/lv_list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollbars="none"></ListView>
</LinearLayout>
item_slideslip.xml

<?xml version="1.0" encoding="utf-8"?>
<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">

    <zxz.sideslipview.view.SideslipView
        android:id="@+id/sv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center_vertical"
            android:orientation="horizontal"
            android:padding="6dp">

            <ImageView
                android:layout_width="40dp"
                android:layout_height="40dp"
                android:src="@drawable/a1" />

            <LinearLayout
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginLeft="10dp"
                android:layout_weight="1"
                android:orientation="vertical">

                <TextView
                    android:id="@+id/tv_name"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="路飞君"
                    android:textColor="#000000"
                    android:textSize="18sp" />

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="6dp"
                    android:text="ONE PIECE " />
            </LinearLayout>

        </LinearLayout>

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:orientation="horizontal">

            <Button
                android:id="@+id/btn_top"
                android:layout_width="100dp"
                android:layout_height="match_parent"
                android:background="#A0A0A0"
                android:text="置顶"
                android:textColor="#FFF" />

            <Button
                android:id="@+id/btn_delete"
                android:layout_width="100dp"
                android:layout_height="match_parent"
                android:background="#F01010"
                android:text="删除"
                android:textColor="#FFF" />
        </LinearLayout>
    </zxz.sideslipview.view.SideslipView>
</RelativeLayout>

这里SideslipView当做ListView中的条目使用。具体Activity实现看demo。

/===========================================/

2、右侧滑菜单

这里写图片描述

  • 仿照这个activity_slidingdemo.xml这个方式就可以实现以上效果
activity_slidingdemo.xml

<?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">

    <zxz.sideslipview.view.SideslipView
        android:id="@+id/sv"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="#DCF6DC"
            android:gravity="center">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="主面板"
                android:textSize="16sp" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:background="#FAE1C6"
            android:gravity="center">

            <TextView
                android:layout_width="160dp"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:text="侧滑面板"
                android:textSize="16sp" />
        </LinearLayout>
    </zxz.sideslipview.view.SideslipView>
</LinearLayout>

-核心部分

  • 就是SideslipView的实现代码
package zxz.sideslipview.view;

import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Rect;
import android.os.Build;
import android.support.v4.view.ViewPager;
import android.support.v4.widget.ViewDragHelper;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.Transformation;
import android.widget.LinearLayout;
import android.widget.Scroller;

/**
 * Created by asusone on 2016/6/24.
 */
public class SideslipView extends LinearLayout {

    private ViewGroup viewContent;
    private ViewGroup viewLeft;
    private int viewLeftWidth;
    private int viewLeftHeight;
    private int x = -1;
    private int distance = 0;
    private Scroller mScroller;
    private int scrollerPosition = 0;
    private ScrollerAnimation scrollerAnimation;
    private String toggleState = "CLOSE";

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

    public SideslipView(Context context) {
        this(context, null);
    }

    private void init() {
        /**设置横向布局**/
        setOrientation(LinearLayout.HORIZONTAL);
        mScroller = new Scroller(getContext());
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        System.out.println("viewLeftWidth:" + viewLeftWidth);
        viewContent.layout(l, t, r, b);
        viewLeft.layout(r, 0, r + viewLeftWidth, b);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        viewContent = (ViewGroup) this.getChildAt(0);
        viewLeft = (ViewGroup) this.getChildAt(1);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        //  viewLeftWidth = viewLeft.getMeasuredWidth();
        int childCount = viewLeft.getChildCount();
        if (childCount == 0) {
            viewLeftWidth = viewLeft.getMeasuredWidth();
        } else {
            for (int i = 0; i < childCount; i++) {
                viewLeftWidth += viewLeft.getChildAt(i).getMeasuredWidth();
            }
        }
        viewLeftHeight = viewLeft.getMeasuredHeight();
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                x = (int) event.getX();
                break;
            case MotionEvent.ACTION_MOVE:
                if (Math.abs(x - event.getX()) > 8) {
                    return true;
                }
                break;
        }
        return super.onInterceptTouchEvent(event);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                x = (int) event.getX();
                break;
            case MotionEvent.ACTION_MOVE:
                if (x == -1) {
                    x = (int) event.getX();
                }
                if (Math.abs(x - event.getX()) > 8) {
                    getParent().requestDisallowInterceptTouchEvent(true);
                }
                int currentDistanceX = (int) (x - event.getX());
                int i = currentDistanceX + distance;
                if (i > viewLeftWidth || i < 0) {
                    break;
                }
                scrollTo(i, 0);
                break;
            case MotionEvent.ACTION_UP:
                if (x - event.getX() > viewLeftWidth / 5) {
                    toggleState = "OPEN";
                } else if (x - event.getX() < -(viewLeftWidth / 5)) {
                    toggleState = "CLOSE";
                }
                distance = distance + (int) (x - event.getX());
                if (distance >= viewLeftWidth) {
                    distance = viewLeftWidth;
                } else if (distance <= 0) {
                    distance = 0;
                }
                x = -1;
                toggle();
                break;
        }
        return true;
    }

    private void toggle() {
        if ("OPEN".equals(toggleState)) {
            //**开**/
            scrollerPosition = viewLeftWidth;
            distance = viewLeftWidth;
            mScroller.startScroll(getScrollX(), 0, -viewLeftWidth - getScrollX(), 0, 400);
            scrollerAnimation = new ScrollerAnimation(this, viewLeftWidth);
        } else if ("CLOSE".equals(toggleState)) {
            //**关**/
            scrollerPosition = 0;
            distance = 0;
            scrollerAnimation = new ScrollerAnimation(this, 0);
        }
        scrollerAnimation.setDuration((long) (0.1 * 1000));
        startAnimation(scrollerAnimation);
    }

    public void open() {
        if ("OPEN".equals(toggleState)) {
            return;
        }
        toggleState = "OPEN";
        toggle();
    }

    public void close() {
        if ("CLOSE".equals(toggleState)) {
            return;
        }
        toggleState = "CLOSE";
        toggle();
    }

    private class ScrollerAnimation extends Animation {
        private View view;
        private int targetScrollX;
        private int startScrollX;
        private int totalValue;

        public ScrollerAnimation(View view, int targetScrollX) {
            this.view = view;
            this.targetScrollX = targetScrollX;

            startScrollX = view.getScrollX();
            totalValue = this.targetScrollX - startScrollX;

            int time = Math.abs(totalValue);
            setDuration(time);
        }
        @Override
        protected void applyTransformation(float interpolatedTime,
                                           Transformation t) {
            super.applyTransformation(interpolatedTime, t);
            int currentScrollX = (int) (startScrollX + totalValue * interpolatedTime);
            view.scrollTo(currentScrollX, 0);
        }
    }
}
SideslipView可以直接拷贝过去用,实在大快人心,使用方法参考以上两个布局文件哦~~

使用方法:直接在布局文件中引用SideslipView,然后在SideslipView下使用两个ViewGroup,第一个ViewGroup则是主区域,第二个ViewGroup则是右侧滑区域。SideslipView是继承LinearLayout的,默认是横向布局。也可以参考下面的布局文件使用!
注意:右区域的大小是根据第二个ViewGroup的大小而动态改变,最好是用dp设置好大小

Demo下载地址:Android Studio工程:http://download.csdn.net/detail/wlcm603/9561057

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值