首先上图,左边为菜单栏显示的样式,右边为滑动过程的样式,滑动结束后应该是菜单栏完全影藏
上代码
布局文件:
1、activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/slideView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<com.example.myslideview.MySlideView
android:id="@+id/myView"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</com.example.myslideview.MySlideView>
</LinearLayout>
2、slide_view.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<LinearLayout
android:id="@+id/slideView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
</LinearLayout>
</LinearLayout>
3、view1.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingTop="5dp" >
<ListView
android:id="@+id/lstView1"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</ListView>
</LinearLayout>
4、view2.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/content" />
</LinearLayout>
代码文件
1、MySlideView.java
package com.example.myslideview;
import android.content.Context;
import android.os.AsyncTask;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.LinearLayout;
public class MySlideView extends LinearLayout {
LinearLayout mLinout;
View view1, view2;// 两个子空间,view1为菜单页,view2为内容页
int v1MaLfMin;// 当前view1的偏移量
int MARGINLEFTMAX;// 移动到最左边是view1的偏移量
public MySlideView(Context context) {
super(context);
}
public MySlideView(Context context, AttributeSet attrs) {
super(context, attrs);
// 读取控件的基础布局
LayoutInflater.from(context).inflate(R.layout.slide_view, this);
mLinout = (LinearLayout) findViewById(R.id.slideView);
}
public void addView(View view, LayoutParams params) {
// 想控件中添加子控件
if (params != null) {
mLinout.addView(view, params);
} else {
mLinout.addView(view);
}
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
if (changed) {
// 设置两个子控件的显示位置,默认显示内容页,即菜单页想向左偏移自身的宽度
view1 = mLinout.getChildAt(0);
view2 = mLinout.getChildAt(1);
MarginLayoutParams leftMargin = (MarginLayoutParams) view1
.getLayoutParams();
leftMargin.leftMargin = 0 - leftMargin.width;
v1MaLfMin = 0 - leftMargin.width;
MARGINLEFTMAX = v1MaLfMin;
view1.setLayoutParams(leftMargin);
}
super.onLayout(changed, l, t, r, b);
}
public void showView(float f) {
//根据当前手指的滑动距离动态改变菜单页的偏移量
MarginLayoutParams leftMargin = (MarginLayoutParams) view1
.getLayoutParams();
if (f != 0) {
int index = (int) (v1MaLfMin + f);
if (index >= MARGINLEFTMAX && index <= 0) {
leftMargin.leftMargin = index;
view1.setLayoutParams(leftMargin);
}
}
}
public void showTo(float f) {
//f大于0滑向右边
//否则滑向左边
MarginLayoutParams leftMargin = (MarginLayoutParams) view1
.getLayoutParams();
if (f > 0) {
// 滑到最右边
(new ScorllScreenTask(1)).execute();
} else {
// 滑到最左边
(new ScorllScreenTask(-1)).execute();
}
}
public void showJudge() {
//手指离开屏幕的时候根据当前偏移量,
//如果当前偏移量大于二分之一,滑动到右侧
//如果当前偏移量小于二分之一,滑动到左侧
MarginLayoutParams leftMargin = (MarginLayoutParams) view1
.getLayoutParams();
if (leftMargin.leftMargin > MARGINLEFTMAX / 2) {
showTo(1);
} else {
showTo(-1);
}
}
/**
* 滑动事件做成一个任务
* 滑动过程中按照一个固定的速度改变偏移量
* 每个一段时间是的线程睡眠一段时间
* 使得滑动时间看起来比较平滑
*/
class ScorllScreenTask extends AsyncTask<Void, Integer, Void> {
int left_right;//判断左滑还是右滑大于零右滑小于零左滑
boolean stop_flag = false;//滑动时间停止标记
int speed;//滑动速率
public ScorllScreenTask(int i) {
//右滑速率为30,左滑速率为-30
left_right = i;
if (left_right > 0) {
speed = 30;
} else {
speed = -30;
}
}
@Override
protected void onPostExecute(Void result) {
int lastMargin = 0;
//动画结束后的最终位置
if (left_right > 0) {
lastMargin = 0;
v1MaLfMin = 0;
} else {
lastMargin = MARGINLEFTMAX;
v1MaLfMin = MARGINLEFTMAX;
}
MarginLayoutParams leftMargin = (MarginLayoutParams) view1
.getLayoutParams();
leftMargin.leftMargin = lastMargin;
view1.setLayoutParams(leftMargin);
super.onPostExecute(result);
}
@Override
protected void onProgressUpdate(Integer... values) {
//动画执行过程中实时更行滑动的位置
MarginLayoutParams leftMargin = (MarginLayoutParams) view1
.getLayoutParams();
leftMargin.leftMargin = values[0];
view1.setLayoutParams(leftMargin);
super.onProgressUpdate(values);
}
@Override
protected Void doInBackground(Void... params) {
while (!stop_flag) {
//每隔25毫秒滑动一个速度
MarginLayoutParams leftMargin = (MarginLayoutParams) view1
.getLayoutParams();
int left = leftMargin.leftMargin;
if (left + speed > MARGINLEFTMAX && left + speed < 0) {
publishProgress(left + speed);
try {
Thread.sleep(25);
} catch (Exception e) {
e.printStackTrace();
}
} else {
stop_flag = true;
}
}
return null;
}
}
}
2、MainActivity.java
package com.example.myslideview;
import java.util.ArrayList;
import java.util.List;
import android.os.Bundle;
import android.os.Handler;
import android.R.integer;
import android.app.Activity;
import android.text.BoringLayout.Metrics;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.GestureDetector;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
import android.widget.LinearLayout.LayoutParams;
public class MainActivity extends Activity {
// 自定义控件
MySlideView mSlideView;
// view1为菜单页,view2为内容页
View view1, view2;
DisplayMetrics dm = new DisplayMetrics();
Handler myHandler = new Handler();
float xDown;// 记录手指按下瞬间的x坐标
float xUp;// 记录手指松开瞬间的x坐标
float xNow;// 记录手指滑动时刻的x坐标
VelocityTracker mVelocityTracker;// 获取手指滑动速率控件
ListView mListView;// 菜单页中的listview
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
// 初始化
mSlideView = (MySlideView) findViewById(R.id.myView);
view1 = getLayoutInflater().inflate(R.layout.view1, null);
mListView = (ListView) view1.findViewById(R.id.lstView1);
setArrayAdapter();
view2 = getLayoutInflater().inflate(R.layout.view2, null);
LayoutParams params1, params2;
getWindowManager().getDefaultDisplay().getMetrics(dm);
// 设置菜单页的宽度为屏幕宽度的四分之三
params1 = new LayoutParams(dm.widthPixels * 3 / 4, dm.heightPixels);
params2 = new LayoutParams(dm.widthPixels, dm.heightPixels);
mSlideView.addView(view1, params1);
mSlideView.addView(view2, params2);
}
private void setArrayAdapter() {
final List<String> arrs = new ArrayList<String>();
arrs.add("消息");
arrs.add("聊天");
arrs.add("找人");
arrs.add("附近");
arrs.add("新鲜事");
arrs.add("公共主页");
arrs.add("微博广角");
arrs.add("新闻事件");
arrs.add("关注");
arrs.add("设置");
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_single_choice, arrs);
mListView.setAdapter(adapter);
mListView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
Toast.makeText(MainActivity.this, arrs.get(arg2),
Toast.LENGTH_SHORT).show();
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void showLogLXL(String lxl) {
Log.e("LXL", lxl);
}
// 根据手指滑动时间控制控件的移动
@Override
public boolean onTouchEvent(MotionEvent event) {
if (mVelocityTracker == null) {
// 速率控件初始化
mVelocityTracker = VelocityTracker.obtain();
}
// 计算没500毫毛的速率
mVelocityTracker.addMovement(event);
mVelocityTracker.computeCurrentVelocity(500);
float speed = mVelocityTracker.getXVelocity();
if (event.getAction() == MotionEvent.ACTION_MOVE) {
// 手指在屏幕上滑动的时候控制控件向滑动的方向移动
xNow = event.getX();
mSlideView.showView(xNow - xDown);
} else if (event.getAction() == MotionEvent.ACTION_DOWN) {
// 记录手指按下的时刻的x坐标
xDown = event.getX();
} else if (event.getAction() == MotionEvent.ACTION_UP) {
if (speed > 1500) {
// 向右滑动的速录大于1500时直接滑动到右侧
mSlideView.showTo(1);
return false;
} else if (speed < -1500) {
// 向左滑动的速度大于1500时直接滑动到左边
mSlideView.showTo(-1);
return false;
}
// 当滑动速率没有超过1500时,在手指松开的时刻根据当前的x坐标判断,
// 如果x坐标大于二分之一则滑到右边否则滑到左边,
// 不管则样不能让控件停在中间,要么滑到左边要么滑到右边
xUp = event.getX();
mSlideView.showJudge();
return false;
}
return super.onTouchEvent(event);
}
}