思路:
效果:
activity_sliding.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<com.maker_huige.ui.SlidingView
android:id="@+id/sv"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="@layout/sliding_left"/>
<include layout="@layout/sliding_center"/>
</com.maker_huige.ui.SlidingView>
</LinearLayout>
sliding_left.xml
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="240dp" android:layout_height="match_parent">
<LinearLayout
android:background="@mipmap/menu_bg"
android:layout_margin="10dp"
android:orientation="vertical"
android:layout_width="240dp"
android:layout_height="match_parent">
<TextView
android:text="新闻"
android:drawableLeft="@mipmap/tab_news"
android:onClick="onTabNews"
style="@style/sliding_left_style"
/>
<TextView
android:text="订阅"
android:drawableLeft="@mipmap/tab_read"
android:onClick="onTabNews"
style="@style/sliding_left_style"
/>
<TextView
android:text="本地"
android:drawableLeft="@mipmap/tab_local"
android:onClick="onTabNews"
style="@style/sliding_left_style"
/>
<TextView
android:text="跟帖"
android:drawableLeft="@mipmap/tab_ties"
android:onClick="onTabNews"
style="@style/sliding_left_style"
/>
<TextView
android:text="图片"
android:drawableLeft="@mipmap/tab_pics"
android:onClick="onTabNews"
style="@style/sliding_left_style"
/>
<TextView
android:text="话题"
android:drawableLeft="@mipmap/tab_ugc"
android:onClick="onTabNews"
style="@style/sliding_left_style"
/>
<TextView
android:text="投票"
android:drawableLeft="@mipmap/tab_vote"
android:onClick="onTabNews"
style="@style/sliding_left_style"
/>
<TextView
android:text="聚合阅读"
android:drawableLeft="@mipmap/tab_focus"
android:onClick="onTabNews"
style="@style/sliding_left_style"
/>
</LinearLayout>
</ScrollView>
sliding_center.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:background="#FFF"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:background="@mipmap/top_bar_bg"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageButton
android:id="@+id/ib_bt"
android:background="@null"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/main_back"
/>
<View
android:layout_width="4dp"
android:layout_height="55dp"
android:background="@mipmap/top_bar_bg"
/>
<TextView
android:layout_marginLeft="20dp"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="黑马新闻"
android:textSize="35dp"
/>
</LinearLayout>
<TextView
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="20dp"
android:text="钓鱼岛是中国的,苍老师是世界的!"
/>
</LinearLayout>
style_left.xml
<style name="sliding_left_style">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:textSize">18sp</item>
<item name="android:textColor">#ADCFD6</item>
<item name="android:clickable">true</item>
<item name="android:drawablePadding">10dp</item>
<item name="android:background">@drawable/bt_bg</item>
</style>
bt_bg.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@color/bt_bg_pressed"></item>
<item android:drawable="@android:color/transparent"/>
</selector>
slidingActivity
package com.maker_huige.myapplication;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageButton;
import com.maker_huige.ui.SlidingView;
/**
* Created by maker_huige on 2016/12/27.
*/
public class slidingActivity extends Activity {
SlidingView sv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sliding);
sv = (SlidingView) findViewById(R.id.sv);
findViewById(R.id.ib_bt).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
sv.switchState();
}
});
}
}
SlidingView
package com.maker_huige.ui;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Scroller;
import android.widget.Toast;
import static android.R.attr.startX;
import static android.R.attr.startY;
/**
* Created by maker_huige on 2016/12/27.
*/
public class SlidingView extends ViewGroup {
View sliding_left;
View sliding_center;
float dowX;
float moveX;
int currenState;
private static final int MENU_STATE = 0;
private static final int MAIN_STATE = 1;
Scroller scroller;
float Xdow;
float Ydow;
public SlidingView(Context context) {
super(context);
init();
}
public SlidingView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public SlidingView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
//水平滑动
scroller = new Scroller(getContext());
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//指定左面板的宽高
sliding_left = getChildAt(0);
sliding_left.measure(sliding_left.getLayoutParams().width,heightMeasureSpec);
//指定主面板的宽高
sliding_center = getChildAt(1);
sliding_center.measure(widthMeasureSpec,heightMeasureSpec);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
/**
*
* @param b 当前控件的尺寸大小, 位置 是否发生了变化
* @param i 当前控件 左边距
* @param i1 当前控件 顶边距
* @param i2 当前控件 右边界
* @param i3 当前控件 下边界
*/
@Override
protected void onLayout(boolean b, int i, int i1, int i2, int i3) {
//摆放内容
sliding_left.layout(-sliding_left.getMeasuredWidth(),0,0,i3);
sliding_center.layout(i,i1,i2,i3);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
dowX = event.getX();
break;
case MotionEvent.ACTION_MOVE:
moveX = event.getX();
//将要发生的偏移量/变化量
int scrollX = (int)(dowX - moveX);
//让变化量累加生效
scrollBy(scrollX,0);
dowX = moveX;
break;
case MotionEvent.ACTION_UP:
int leftCount = (int) (-sliding_left.getMeasuredWidth() / 2);
if(getScrollX() <= leftCount){
currenState = MENU_STATE;
updateCurrenContent();
}else{
currenState = MAIN_STATE;
updateCurrenContent();
}
break;
}
return true;
}
private void updateCurrenContent() {
int startX = getScrollX();
int dx = 0;
if(currenState == MENU_STATE){
//菜单模式
dx = -sliding_left.getMeasuredWidth() - startX;
// scrollTo(-sliding_left.getMeasuredWidth(),0);
}else{
dx = 0 - startX;
// scrollTo(0,0);
}
/**开始的x值
* 开始的y值
* 将要发生的水平变化量,移动的X距离
* 数据模拟持续市场
*/
//开始平滑的模拟数据
int duration = Math.abs(dx * 2);
scroller.startScroll(startX,0,dx,0,duration);//平滑滚动
invalidate();// 重绘界面 -> drawChild() -> computeScroll();
}
//2.维持动画的持续
@Override
public void computeScroll() {
super.computeScroll();
if (scroller.computeScrollOffset()){
int currX = scroller.getCurrX();
scrollTo(currX,0);
invalidate();// 重绘界面-> drawChild() -> computeScroll();循环
}
}
public void open(){
currenState = MENU_STATE;
updateCurrenContent();
}
public void close(){
currenState = MAIN_STATE;
updateCurrenContent();
}
public void switchState(){
if(currenState == MENU_STATE){
close();
}else{
open();
}
}
//拦截事件
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
switch (ev.getAction()){
case MotionEvent.ACTION_DOWN:
Xdow = ev.getX();
Ydow = ev.getY();
break;
case MotionEvent.ACTION_MOVE:
float Xoffset = Math.abs(ev.getX() - Xdow);
float Yoffset = Math.abs(ev.getY() - Ydow);
if(Xoffset > Yoffset && Xoffset >5){
return true;
}
break;
}
return super.onInterceptTouchEvent(ev);
}
}