目标:制作现阶段App中常见的左右滑动ListView。
特点:有多种方法实现,一种是使用官方menudrawer;一种是开源的SlidingMenu;还有其他各种各样的方法。我在这里使用的是自定义方法(相对使用各种现成的控件,这种方法倒不是麻烦,不过就是要判断各种不同的情况,要没有什么bug需要花费不少心机;好处就是不用引入一大堆包,而且有一种尽在掌握的感觉,呵呵~~)
下面是一个从右边滑动出来的菜单例子,e.g.
SlidingViewGroup.java
package com.testApp5;
import android.app.Activity;
import android.content.Context;
import android.graphics.Point;
import android.os.Handler;
import android.os.Message;
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.Animation.AnimationListener;
import android.view.animation.TranslateAnimation;
public class SlidingViewGroup extends ViewGroup {
private final float WIDTH_RATE = 0.65f;
private Main mainView;
private Side sideView;
private Point point;
private boolean isSliding = false;
private boolean isMoveOut = false;
private int xSideLeft;
private int sideWidth;
private int xMoveSideLeft;
private int xMoveStart;
private int yMoveStart;
private int yMoveSideTop;
private int yMoveSideBottom;
private Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case 1: // side出现
moveIn();
break;
case 3: // side收起来
moveOut();
break;
case 5: // 拖动时
moving();
break;
default:
break;
}
}
};
public void init(Activity activity, Point point) {
initParam(point);
initView(activity);
}
public void initParam(Point point) {
this.point = point;
xSideLeft = (int) (point.x * (1 - WIDTH_RATE));
sideWidth = (int) (point.x * WIDTH_RATE);
xMoveSideLeft = xSideLeft;
}
public void initView(Activity activity) {
mainView = new Main(this.getContext(), this);
sideView = new Side(activity, this.getContext(), this);
this.addView(mainView.getView());
this.addView(sideView.getView());
mainView.getView().setVisibility(View.VISIBLE);
sideView.getView().setVisibility(View.GONE);
}
public void moveIn() {
TranslateAnimation mShowAnimation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 1.0f,
Animation.RELATIVE_TO_SELF, 0.0f,
Animation.RELATIVE_TO_SELF, 0.0f,
Animation.RELATIVE_TO_SELF, 0.0f);
mShowAnimation.setDuration(300);
sideView.getView().setVisibility(View.VISIBLE);
sideView.getView().startAnimation(mShowAnimation);
}
public void moveOut() {
TranslateAnimation mHideAnimation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.0f,
Animation.RELATIVE_TO_SELF, 1.0f,
Animation.RELATIVE_TO_SELF, 0.0f,
Animation.RELATIVE_TO_SELF, 0.0f);
mHideAnimation.setDuration(300);
sideView.getView().startAnimation(mHideAnimation);
mHideAnimation.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
// TODO Auto-generated method stub
}
@Override
public void onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub
}
@Override
public void onAnimationEnd(Animation animation) {
sideView.getView().setVisibility(View.GONE);
}
});
}
public void moving() {
sideView.getView().layout(xMoveSideLeft, yMoveSideTop, (xMoveSideLeft + sideWidth), yMoveSideBottom);
}
public void moveHandler() {
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
Message msg = new Message();
if (View.VISIBLE == sideView.getView().getVisibility()) {
if (isMoveOut) {
// side收起来
msg.what = 3;
mHandler.sendMessage(msg);
mHandler.removeCallbacks(this);
} else if (isSliding) {
// 拖动时
msg.what = 5;
mHandler.sendMessage(msg);
}
} else {
// side出现
msg.what = 1;
mHandler.sendMessage(msg);
mHandler.removeCallbacks(this);
}
};
}, 0);
}
public boolean dispatchTouchEvent(MotionEvent ev) {
if (View.VISIBLE == sideView.getView().getVisibility() && ev.getX() > xSideLeft) { // 只处理side收起来和side上触摸事件
int action = ev.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:// 按下去
yMoveSideTop = (int)sideView.getView().getY();
yMoveSideBottom = sideView.getView().getBottom();
xMoveStart = (int)ev.getX();
yMoveStart = (int)ev.getY();
isSliding = false;
isMoveOut = false;
break;
case MotionEvent.ACTION_MOVE:// 拖动时
if (!isSliding && Math.abs(ev.getX() - xMoveStart) >= Math.abs(ev.getY() - yMoveStart)) {
isSliding = true;
}
if (isSliding) { //拖动
// Log.println(Log.ASSERT, "custom", "left:" + xSideLeft + ", sliding:" + xMoveSideLeft);
xMoveSideLeft = (int) (xSideLeft + (ev.getX() - xMoveStart));
if (xMoveSideLeft < xSideLeft) {
xMoveSideLeft = xSideLeft + 1; // +1 是为了防止由于计算误差而漏边界
} else if (xMoveSideLeft > point.x) {
xMoveSideLeft = point.x;
}
moveHandler();
}
break;
case MotionEvent.ACTION_UP:// 放开时
if (!isMoveOut && (ev.getX() - xMoveStart > 15)) { // 15而不是0,是为了避免手指微小误差
isMoveOut = true;
}
if (isMoveOut) { //side收起来
moveHandler();
}
super.dispatchTouchEvent(ev);
return false;
}
}
return super.dispatchTouchEvent(ev);
}
public SlidingViewGroup(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
mainView.getView().layout(0, 0, point.x, point.y);
sideView.getView().layout((int) (point.x * (1 - WIDTH_RATE)), 0, point.x, point.y);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
mainView.getView().measure(widthMeasureSpec, heightMeasureSpec);
sideView.getView().measure(MeasureSpec.UNSPECIFIED, heightMeasureSpec);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
public boolean isSliding() {
return isSliding;
}
public boolean isMoveOut() {
return isMoveOut;
}
}
package com.testApp5;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;
public class Main {
private Context context;
private View mainView;
private ListView listView;
public Main(final Context context, final SlidingViewGroup slidingViewGroup) {
this.context = context;
mainView = LayoutInflater.from(context).inflate(R.layout.main, null);
listView = (ListView) this.mainView.findViewById(R.id.main_list);
listView.setAdapter(new MainAdapter());
listView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Toast.makeText(context, "item_click", Toast.LENGTH_SHORT).show();
slidingViewGroup.moveHandler();
}
});
}
public View getView() {
return mainView;
}
public class MainAdapter extends BaseAdapter {
@Override
public int getCount() {
return mMainStrings.length;
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return null;
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView t = new TextView(context);
t.setTextSize(24);
t.setPadding(0, 25, 0, 25);
t.setText(mMainStrings[position]);
return t;
}
}
private String[] mMainStrings = {
"感冒", "咳嗽"};
}
package com.testApp5;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.Message;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;
public class Side {
private View sideView;
private ListView listView;
private View footer;
final private int pageSize = 20;
private List<String> sideData = new ArrayList<String>();
private BaseAdapter adapter;
private boolean canLoad = true;
private AtomicInteger currentPage = new AtomicInteger(1);
private SlidingViewGroup slidingViewGroup;
public Side(final Activity activity, final Context context, final SlidingViewGroup slidingViewGroup) {
setSlidingViewGroup(slidingViewGroup);
sideView = LayoutInflater.from(context).inflate(R.layout.side, null);
...
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ListView
android:id="@+id/main_list"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
>
</ListView>
</LinearLayout>
side.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@android:color/background_dark"
android:orientation="vertical" >
<ListView
android:id="@+id/side_list"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2"
>
</ListView>
</LinearLayout>
有空可以参考一下:http://www.cnblogs.com/gzggyy/p/3182472.html,http://www.linuxidc.com/Linux/2013-05/83724.htm