您的位置:首页 > 移动开发 > Android开发

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

2016-06-27 18:16 555 查看
一直没有写博客的习惯,一直都是看别人的博客,学习别人的东西。平时工作中总会遇到或大或小的问题,往往是上百度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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: