作为一个刚入行的人来说实现效果基本就是Copy改,但是最近公司要求做的应用其中有人人的滑动效果,在网上查了很多,也有很多人实现,但总感觉太繁琐,可能自己太菜看不太明白为什么要搞的那么麻烦,所以自己在看了ViewGroup的一些文章打算自己实现一个。
首先新建个Android项目:
二、我实现此效果用的是自定义ViewGroup,至于让前面一个页面滑动多少我是根据左上角这个Button的宽和给一个相对合适的值来确定的,代码如下:
package luffy.com.cn.view;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.TranslateAnimation;
public class SlideMenuView extends ViewGroup {
private int gap;
public SlideMenuView(Context context, View backView, View frontView) {
super(context);
LayoutParams lp = new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT);
addView(backView, lp);
addView(frontView, lp);
}
public SlideMenuView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
checkChildCount();
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
int height = child.getMeasuredHeight();
int width = child.getMeasuredWidth();
child.layout(0, 0, width, height);
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
if (widthMode != MeasureSpec.EXACTLY) {
throw new IllegalStateException(
"ScrollLayout only canmCurScreen run at EXACTLY mode!");
}
final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
if (heightMode != MeasureSpec.EXACTLY) {
throw new IllegalStateException(
"ScrollLayout only can run at EXACTLY mode!");
}
final int count = getChildCount();
for (int i = 0; i < count; i++) {
getChildAt(i).measure(widthMeasureSpec, heightMeasureSpec);
}
}
/**
* 使用之前先传入需要留下间隔的宽度。或者调用setGap(final View measureView)。
*
* @param gap
* 间隔宽度
*/
public void setGap(int gap) {
this.gap = gap;
// invalidate();
}
/**
* 使用之前先传入要留下的空间。或者调用setGap(int gap)。
*
* @param measureView
* 间隔宽度(这个里面中就是左上角按钮的宽度)
* @param gap
* 间隔修正值,无需修正传入0(设置滑动后按钮右边离屏幕右边的距离)
*/
public void setGap(final View measureView, final int resize) {
ViewTreeObserver vto = measureView.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
int width = measureView.getMeasuredWidth();
gap = width;
getChildAt(0).setPadding(0, 0, gap + resize, 0);
setGap(gap + resize);
}
});
}
private void checkChildCount() {
if (2 != getChildCount()) {
throw new IndexOutOfBoundsException("只允许拥有2个子View!");
}
}
private void ani(final int from, final int to, final int left) {
final View v = getChildAt(1);
TranslateAnimation translateAnimation = new TranslateAnimation(from,
to, 0, 0);
translateAnimation.setInterpolator(new DecelerateInterpolator());
translateAnimation.setFillAfter(true);
translateAnimation.setDuration(300);
translateAnimation.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationRepeat(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
v.clearAnimation();
v.layout(left, 0, left + getWidth(), v.getHeight());
}
});
v.startAnimation(translateAnimation);
}
public boolean isMenuOpen() {
if (getChildAt(1).getLeft() == 0) {
return false;
}
return true;
}
public void sliding() {
if (isMenuOpen()) {
ani(0, gap - getWidth(), 0);
} else {
ani(0, getWidth() - gap, getWidth() - gap);
}
}
}
三、由于有两个界面所以我把后面的那个界面单独提了出来,不至于把所有的代码写在一个Activity中,感觉太乱!(加了个Button测试下是不是能点到,之前在网上下了个demo效果是有,但后面这个界面没有点击事件 ^^)代码如下:
package luffy.com.cn.view;
import zhangkai.com.cn.viewgroup.R;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class BackView {
private View view;
private Button btn;
private TextView textView;
public BackView(Context context){
LayoutInflater inflater = LayoutInflater.from(context);
view = inflater.inflate(R.layout.back_view, null);
init();
}
private void init(){
btn = (Button)view.findViewById(R.id.back_btn);
textView = (TextView)view.findViewById(R.id.back_text);
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
textView.setText("貌似是可以的~~~~~");
}
});
}
public View getView(){
return view;
}
}
四、Activity代码:
package luffy.com.cn.activity;
import luffy.com.cn.view.BackView;
import luffy.com.cn.view.SlideMenuView;
import zhangkai.com.cn.viewgroup.R;
import android.app.Activity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;
public class ViewGroupRRActivity extends Activity {
private SlideMenuView slideMenu;
private LinearLayout back_view,front_view;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.main);
LayoutInflater inflater = LayoutInflater.from(ViewGroupRRActivity.this);
front_view = (LinearLayout) inflater.inflate(R.layout.main, null);
BackView bv = new BackView(ViewGroupRRActivity.this);
back_view = (LinearLayout) bv.getView();
slideMenu = new SlideMenuView(ViewGroupRRActivity.this,back_view,front_view);
Button btn = (Button)front_view.findViewById(R.id.button1);
slideMenu.setGap(btn, 5);
setContentView(slideMenu);
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
slideMenu.sliding();
}
});
}
}
五、XML代码:
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:id="@+id/frontView"
android:background="#9B8579"
android:orientation="vertical" >
<Button
android:id="@+id/button1"
android:layout_width="60dp"
android:layout_height="40dp"
android:text="Button" />
<ListView
android:id="@+id/listView2"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
</ListView>
</LinearLayout>
back_view.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:background="#1C75BC"
android:orientation="vertical" >
<Button
android:id="@+id/back_btn"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="干点啥" />
<TextView
android:id="@+id/back_text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>
在传一下效果图: