最终效果图
![5337239-d05846026770c91b.gif](https://i-blog.csdnimg.cn/blog_migrate/84b796f9a16d25a80dd475784614ef0e.webp?x-image-process=image/format,png)
2017-09-20-02mzZzzz.gif
思路:
打开QQ之后我个人感觉,QQ的侧滑栏和系统的一个控件很像,但是由于好奇所以试了一下,感觉近乎完美
1.有两个FrameLayout,一个测量时是全屏幕(中间的),一个测量时是半边屏根据QQ的滑动初步判断为1/5,所以获取当前屏幕宽度在除以5[左边控件宽 = 屏幕宽度 - 屏幕宽度 / 5],就能得到左边控件所要的宽度,然后使用FragmeLayout的setTranslationX();来移动当前控件的X位置
全部代码
package com.example.downlist.view;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.Scroller;
/**
* Created by Administrator on 2017/9/15.
*/
//仿QQ侧边栏
public class QQLiftView extends FrameLayout {
private int startX;
private int mid = 0;
private FrameLayout midF;
private FrameLayout liftF;
//记录相加的值
private int size;
//防止越界的值
private int right1;
private Scroller scroller;
private int weiht;
private int liftIntWight;
private int liftIntWight_;
public QQLiftView(Context context) {
super(context);
initView(context);
}
public QQLiftView(Context context, AttributeSet attrs) {
super(context, attrs);
initView(context);
}
public QQLiftView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView(context);
}
public void initView(Context context) {
scroller = new Scroller(context);
}
@Override
public void computeScroll() {
super.computeScroll();
if (scroller.computeScrollOffset()) {
liftF.setTranslationX(scroller.getCurrX());
size = scroller.getCurrX();
midF.setTranslationX(scroller.getCurrX() / 3);
invalidate();
}
}
private void scToIndex(int index) {
scroller.startScroll(size, 0, index - size, 0);
invalidate();
}
@Override
protected void onLayout(boolean b, int i, int i1, int i2, int i3) {
//获取中间的Fragment
if (midF == null)
midF = (FrameLayout) getChildAt(0);
if (liftF == null)
liftF = (FrameLayout) getChildAt(1);
//获取左边的Fragment
right1 = midF.getRight();
//获取屏幕宽
int right = getRight();
int right5 = right / 5;
liftF.layout(i, i1, i2, i3);
liftIntWight = i2 - right5;
liftIntWight_ = liftIntWight / 3;
midF.layout(-liftIntWight_, i1, (liftIntWight - liftIntWight_), i3);
// measureView(i2 - right5);
Log.e("----", "onLayout: " + (right - right5));
weiht = (i2 - right5);
//获取子类,重新测量位置
//startLayout();
}
//开始量测位置
public void startLayout() {
for (int i = 0; i < midF.getChildCount(); i++) {
midF.getChildAt(i).layout(
0,
midF.getChildAt(i).getTop(),
liftIntWight,
midF.getChildAt(i).getBottom()
);
}
for (int i = 0; i < liftF.getChildCount(); i++) {
liftF.getChildAt(i).layout(
liftF.getChildAt(i).getLeft(),
liftF.getChildAt(i).getTop(),
liftF.getChildAt(i).getRight(),
liftF.getChildAt(i).getBottom()
);
}
}
//获取要测量的子类
public void meIndex() {
for (int i = 0; i < liftF.getChildCount(); i++) {
View childAt = liftF.getChildAt(i);
ViewGroup.LayoutParams layoutParams = childAt.getLayoutParams();
if (layoutParams == null) {
layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
}
int childMeasureSpec = ViewGroup.getChildMeasureSpec(0, 0, layoutParams.width);
int height;
int tempHei = layoutParams.height;
if (tempHei == 0) {
height = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
} else {
height = MeasureSpec.makeMeasureSpec(tempHei, MeasureSpec.EXACTLY);
}
childAt.measure(childMeasureSpec, height);
}
for (int i = 0; i < midF.getChildCount(); i++) {
View childAt = midF.getChildAt(i);
ViewGroup.LayoutParams layoutParams = childAt.getLayoutParams();
if (layoutParams == null) {
layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
}
int childMeasureSpec = ViewGroup.getChildMeasureSpec(0, 0, layoutParams.width);
int height;
int tempHei = layoutParams.height;
if (tempHei == 0) {
height = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
} else {
height = MeasureSpec.makeMeasureSpec(tempHei, MeasureSpec.EXACTLY);
}
childAt.measure(childMeasureSpec, height);
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (liftF == null) {
liftF = (FrameLayout) getChildAt(1);
}
if (midF == null) {
midF = (FrameLayout) getChildAt(0);
}
//开始测量
meIndex();
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
startX = (int) event.getX();
break;
case MotionEvent.ACTION_MOVE:
int endX = (int) event.getX();
mid = endX - startX;
//scrollBy(-mid, 0);
ScrollByView(mid);
startX = endX;
//invalidate();
Log.e("----", "onTouchEvent: " + mid);
break;
case MotionEvent.ACTION_UP:
isLiftRight();
break;
}
return true;
}
//处理是要左划还是要往右滑
private void isLiftRight() {
//中间值
int mid = weiht / 2;
if (size > weiht) {
liftF.setTranslationX(weiht);
size = weiht;
return;
}
if (size < 0) {
liftF.setTranslationX(0);
size = 0;
return;
}
if (size > mid) {
//向右
scToIndex(weiht);
Log.e("大小", "isLiftRight: " + "向右滑");
}
if (size < mid) {
//向左
scToIndex(0);
Log.e("大小", "isLiftRight: " + "向左滑");
}
}
public void ScrollByView(int x) {
size += x;
if (size < weiht && size >= 0) {
liftF.setTranslationX(size);
midF.setTranslationX(size / 3);
}
}
}
//Layout界面代码
<?xml version="1.0" encoding="utf-8"?>
<com.example.downlist.view.QQLiftView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/mySheView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<FrameLayout
android:id="@+id/mid"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#123456">
<LinearLayout
android:layout_width="300dp"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:layout_width="match_parent"
android:layout_height="200dp"
android:scaleType="fitXY"
android:src="@drawable/hxh" />
</LinearLayout>
</FrameLayout>
<FrameLayout
android:id="@+id/lift"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#654321">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:layout_width="match_parent"
android:layout_height="200dp"
android:scaleType="fitXY"
android:src="@drawable/hxh" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="dshshfhdskjfhdsf" />
</LinearLayout>
</FrameLayout>
</com.example.downlist.view.QQLiftView>
希望以上代码对你的自定义控件有所帮助 0.0
如果那块有不懂得请联我哟...0.0 哈哈
----XINHAO_HAN
Demo下载:
链接: https://pan.baidu.com/s/1i5P6WML 密码: 3283