欢迎访问移动开发之家(rcyd.net),关注移动开发教程。移动开发之家  移动开发问答|  每日更新
页面位置 : > > > 内容正文

android 自定义ViewGroup和对view进行切图动画实现滑动菜单SlidingMenu

来源: 开发者 投稿于  被查看 27611 次 评论:55

android 自定义ViewGroup和对view进行切图动画实现滑动菜单SlidingMenu


    示意图就不展示了,和上一节的一样,滑动菜单SlidingMenu效果如何大家都比较熟悉,在这里我简单说明一下用自定义ViewGroup来实现.
    实现方法:我们自定义一个ViewGroup实现左右滑动,第一屏隐藏,第二屏显示.
    代码如下:
[java]
package com.jj.sliding_6; 
 
import android.content.Context; 
import android.util.AttributeSet; 
import android.util.Log; 
import android.view.View; 
import android.view.ViewGroup; 
import android.view.ViewTreeObserver; 
import android.view.View.MeasureSpec; 
import android.view.ViewTreeObserver.OnGlobalLayoutListener; 
import android.widget.AbsoluteLayout; 
import android.widget.LinearLayout; 
import android.widget.ListView; 
import android.widget.RelativeLayout; 
import android.widget.Scroller; 
 
/***
 * 自定义view
 * 
 * @author zhangjia
 * 
 */ 
public class MyViewGroup extends ViewGroup { 
    private Scroller scroller;// 滑动 
    private int distance;// 滑动距离 
 
    private View menu_view, content_view; 
    private int duration = 500; 
 
    private ViewTreeObserver viewTreeObserver; 
    private Context context; 
    private CloseAnimation closeAnimation; 
 
    public static boolean isMenuOpned = false;// 菜单是否打开 
 
    public MyViewGroup(Context context) { 
        super(context, null); 
    } 
 
    public void setCloseAnimation(CloseAnimation closeAnimation) { 
        this.closeAnimation = closeAnimation; 
    } 
 
    public MyViewGroup(Context context, AttributeSet attrs) { 
        super(context, attrs); 
        this.context = context; 
        scroller = new Scroller(context); 
    } 
 
    public void setDistance(int distance) { 
        this.distance = distance; 
    } 
 
    @Override 
    protected void onLayout(boolean changed, int l, int t, int r, int b) { 
        if (changed) { 
            menu_view = getChildAt(0);// 获取滑动菜单的view 
            content_view = getChildAt(1);// 获得主页view 
 
            // 相当于fill_parent 
            content_view.measure(0, 0); 
            content_view.layout(0, 0, getWidth(), getHeight()); 
        } 
    } 
 
    @Override 
    public void computeScroll() { 
        Log.e("jj", "isMenuOpned=" + isMenuOpned); 
        if (scroller.computeScrollOffset()) { 
            scrollTo(scroller.getCurrX(), scroller.getCurrY()); 
            postInvalidate();// 刷新 
            if (closeAnimation != null) 
                closeAnimation.closeMenuAnimation(); 
 
        }else{ 
            MainActivity.isScrolling=false; 
        } 
    } 
 
    void showMenu() { 
        Log.e("jj", "shoeMenu"); 
        isMenuOpned = true; 
        scroller.startScroll(getScrollX(), 0, -distance, 0, duration); 
        invalidate();// 刷新 
    } 
 
    // 关闭菜单(执行自定义动画) 
    void closeMenu() { 
        Log.e("jj", "closeMenu"); 
        isMenuOpned = false; 
        scroller.startScroll(getScrollX(), 0, distance, 0, duration); 
 
        invalidate();// 刷新 
    } 
 
    // 关闭菜单(执行自定义动画) 
    void closeMenu_1() { 
        isMenuOpned = false; 
        scroller.startScroll(getScrollX(), 0, distance - getWidth(), 0, 
                duration); 
        invalidate();// 刷新 
    } 
 
    // 关闭菜单(执行自定义动画) 
    void closeMenu_2() { 
        isMenuOpned = false; 
        scroller.startScroll(getScrollX(), 0, getWidth(), 0, duration); 
        invalidate();// 刷新 
    } 
 
    /***
     * Menu startScroll(startX, startY, dx, dy)
     * 
     * dx=e1的减去e2的x,所以右移为负,左移动为正 dx为移动的距离,如果为正,则标识向左移动|dx|,如果为负,则标识向右移动|dx|
     */ 
    void slidingMenu() { 
        Log.e("jj", "slidingMenu"); 
        // 没有超过半屏 
        if (getScrollX() > -getWidth() / 2) { 
            scroller.startScroll(getScrollX(), 0, -getScrollX(), 0, duration); 
            isMenuOpned = false; 
        } 
        // 超过半屏 
        else if (getScrollX() <= -getWidth() / 2) { 
            scroller.startScroll(getScrollX(), 0, -(distance + getScrollX()), 
                    0, duration); 
            isMenuOpned = true; 
        } 
 
        invalidate();// 刷新 
        Log.v("jj", "getScrollX()=" + getScrollX()); 
    } 

 
  abstract class CloseAnimation { 
    // 点击list item 关闭menu动画 
    public void closeMenuAnimation() { 
 
    }; 

上诉大部分我都加以注释,想必不用我解释太多,大家仔细看都应该可以看懂.
之后我们只需要在MainActivity中把要显示的view添加进去就可以了。
运行效果:\      \
       
 我把源码上传网上,大家可以下载运行,如有不足请留言.
说明一点:listview上下左右滑动冲突没有解决,不过我运行看过很多应用,要么listview不能左右滑动,要么能左右滑动但是listview不到一屏.

 

下面我介绍另外一种方法,这种方法比较简单,但是有点不实用.不过对SlidingMenu滑动菜单要求不高的应用完全可以了,如:云中书城等,没有用到手势时时滑动.
实现方法:我们在点击或者滑动的时候获取当前view的切图bitmap,然后将这个bitmap传递到打开后的activity,在这个activity中布局具体如下:
[java]
<?xml version="1.0" encoding="utf-8"?> 
<AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/layout" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" > 
 
    <FrameLayout 
        android:id="@+id/slideout_placeholder" 
        android:layout_width="fill_parent" 
        android:layout_height="fill_parent" 
        android:background="#777777" > 
 
        <ListView 
            android:id="@+id/list" 
            android:layout_width="fill_parent" 
            android:layout_height="fill_parent" 
            android:cacheColorHint="#00000000" /> 
    </FrameLayout> 
 
    <ImageView 
        android:id="@+id/slidedout_cover" 
        android:layout_width="fill_parent" 
        android:layout_height="fill_parent" 
        android:scaleType="fitXY" /> 
 
</AbsoluteLayout> 
这种布局目的就是让用户觉得我们操作的是一个view.
具体实现:我将代码上传网上,大家自行下载运行,有不足之处,自行调整.
效果图;


 

 


 

相关文章

    暂无相关文章

用户评论