新手 自定义SlidingMenu控件

最近花了很多时间上去完成 侧滑SlidingMenu  ,SlidingMenu的是一种比较新的设置界面或配置界面效果,在主界面左滑或者右滑出现设置界面,能方便的进行各种操作也在网上找了好多大神的案例看了,看起来很简单,如果不动手的话,其实还是有一点点难度的,当然了,这是对于新手的我来说,还是多敲多看,还有就是DrawerLayout 也能实现侧滑的功能。对于作为未来准程序猿来说,最开心的莫过于就是百思不得其解的问题由自己解决的那一刻,很有成就感,由于第一次用,对这个博客的编写好多内容都不太熟悉使用,勿怪,

废话不多说了,先看看效果图,




下面看一下资源整体目录





1.我们先来看一下布局代码;activity_left:

最外部用了FragmeLayout ,嵌套ScrollView  使用线性布局LinearLayout    还使用了drawableLeft这个属性

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/menu_left_frag"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >


    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@drawable/left" >


        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="center_vertical"
            android:orientation="vertical" >


            <TextView
                android:id="@+id/tab_news"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@drawable/first_normal"
                android:drawableLeft="@drawable/tab_focus"
                android:gravity="center"
                android:text="新闻"
                android:textColor="#000"
                android:textSize="20sp"
                android:textStyle="bold" />


            <TextView
                android:id="@+id/tab_read"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@drawable/middle_normal"
                android:drawableLeft="@drawable/tab_news"
                android:gravity="center"
                android:text="订阅"
                android:textColor="#000"
                android:textSize="20sp"
                android:textStyle="bold" />


            <TextView
                android:id="@+id/tab_local"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@drawable/middle_normal"
                android:drawableLeft="@drawable/tab_local"
                android:gravity="center"
                android:text="本地"
                android:textColor="#000"
                android:textSize="20sp"
                android:textStyle="bold" />


            <TextView
                android:id="@+id/tab_ties"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@drawable/middle_normal"
                android:drawableLeft="@drawable/tab_ties"
                android:gravity="center"
                android:text="跟帖"
                android:textColor="#000"
                android:textSize="20sp"
                android:textStyle="bold" />


            <TextView
                android:id="@+id/tab_pics"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@drawable/middle_normal"
                android:drawableLeft="@drawable/tab_pics"
                android:gravity="center"
                android:text="图片"
                android:textColor="#000"
                android:textSize="20sp"
                android:textStyle="bold" />


            <TextView
                android:id="@+id/tab_focus"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@drawable/middle_normal"
                android:drawableLeft="@drawable/tab_focus"
                android:gravity="center"
                android:text="话题"
                android:textColor="#000"
                android:textSize="20sp"
                android:textStyle="bold" />


            <TextView
                android:id="@+id/tab_vote"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@drawable/middle_normal"
                android:drawableLeft="@drawable/tab_vote"
                android:gravity="center"
                android:text="投票"
                android:textColor="#000"
                android:textSize="20sp"
                android:textStyle="bold" />


            <TextView
                android:id="@+id/tab_ugc"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@drawable/last_normal"
                android:drawableLeft="@drawable/tab_ugc"
                android:gravity="center"
                android:text="聚合阅读"
                android:textColor="#000"
                android:textSize="20sp"
                android:textStyle="bold" />
        </LinearLayout>
    </ScrollView>


</FrameLayout>


2. 主页布局activity_menu.xml :


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/menu_left_frag"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >


    <LinearLayout
        android:id="@+id/ll"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/top_bar_divider"
        android:gravity="center_vertical"
        android:orientation="horizontal" >


        <ImageView
            android:id="@+id/back"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/th_tap"
            android:clickable="true"
            android:focusable="true" />


        <View
            android:id="@+id/view"
            android:layout_width="5dp"
            android:layout_height="50dp"
            android:background="@drawable/top_bar_bg" />


        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:paddingLeft="10dp"
            android:text="弘博新闻客户端"
            android:textColor="#fff"
            android:textSize="25sp"
            android:textStyle="bold" />


        
    </LinearLayout>


    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@id/ll"
        android:background="@drawable/e"
        android:gravity="center" />


    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@id/ll"
        android:background="@drawable/menu"
        android:gravity="center"
        android:text="欢迎进入弘博新闻客户端"
        android:textColor="#Ce0000"
        android:textSize="30sp" />


</RelativeLayout>


3.最主要的就是activity_main.xml: 可以看到,我引入的是自己自定义的SlidingMenu, 使用include 加入菜单页和主页


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >


    <com.example.slidingmenu.view.SlidingMenu
        android:id="@+id/myslidingmenu"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >


<!-- 0   作为标识-->
        <include layout="@layout/activity_left" />

<!-- 1   作为标识 -->
        <include layout="@layout/activity_menu" />


       
    </com.example.slidingmenu.view.SlidingMenu>


</RelativeLayout>

4.引入 android.support. V4 包  



如果引入,运行时出错的话, 解决方法如下 1.Windows---->Android SDK Manager ---->在Packages列表下最后一列  Extras  ,勾选 Android Support  Ropository  ---> Install  14 packages....  当更新完 后 会在你自己安装SDK的目录下 会生成一个andorid的文件夹






这里个人建议先这样做,这样在新建项目的时候就不用引入v4的包了,会在新建项目的时候自动加入v4的包


5. 自定义SildingMenu 

package com.example.slidingmenu.view;


import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.widget.HorizontalScrollView;
import android.widget.Scroller;


public class SlidingMenu extends ViewGroup{




//左边菜单页
private View menuView;
//主页
private View mainView;
//右边页
private View rightView;
private int menuWidth;
private int rightWidth;
private int downX;
private int downY;


private int downRX;
private int downRY;


private Scroller scroller;
private int touchSlop;
private int scrollX;
private int currentScreen =SCREEN_MAIN ;
private static final int SCREEN_MAIN = 1;
private static final int SCREEN_MENU = 0;
private static final String TAG = "SlidingMenu";
//构造方法
public SlidingMenu(Context context) {
super(context);
// this(context,null);
init();
}
//构造方法
public SlidingMenu(Context context, AttributeSet attrs) {
super(context, attrs);
// this(context,attrs,0);
init();
}
private void init() {
// TODO Auto-generated method stub
scroller = new Scroller(getContext());


touchSlop = ViewConfiguration.get(getContext()).getTouchSlop();
System.out.println("touchslop:"+touchSlop);


}


/**
* 测量
* 1.自定义控件
* 2.菜单页
* 3.首页
*  widthMeasureSpec heightMeasureSpec : 当前控件的宽高
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// 1.自定义控件
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// 测量菜单页和首页
// 根据布局文件中的角标获取子控件的对象
menuView =  getChildAt(0);
// 2.菜单页  左边
menuWidth = menuView.getLayoutParams().width;
menuView.measure(menuWidth, heightMeasureSpec);
Log.i(TAG, "menuView:" + menuWidth );
// 3.首页
mainView =  getChildAt(1);
Log.i(TAG, "mainView:" + mainView );
mainView.measure(widthMeasureSpec, heightMeasureSpec);
// //4.右边页
// rightView = getChildAt(2);
// //获取右边页面的宽度
// rightWidth = rightView.getLayoutParams().width +widthMeasureSpec;
// rightView.measure(rightWidth, heightMeasureSpec);


}


/**
*   排版
*   changed : 是否有最新的位置
*   l t r b : 控件的左上右下的位置
*/
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {


//标题的位置
menuView =  getChildAt(0);
menuView.layout(-menuView.getMeasuredWidth(), t, 0, b);
//主页的位置
mainView =  getChildAt(1);
mainView.layout(l, t, r, b);
// //右边页的位置
// rightView = getChildAt(2);
// rightView.layout(l,t,0, rightView.getMeasuredWidth());


}


// 事件拦截操作,主要用来判断是否拦截事件,是否传递给子控件事件  
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
//判断横向滑动还是竖向滑动,如果是横向滑动,拦截事件,如果是竖向滑动,放开事件不去拦截
//可以根据x轴和y的轴距离来判断
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
downX = (int) ev.getX();
// downRX = (int) ev.getX();
Log.i(TAG, "X轴的位置:" + downX );
break;


case MotionEvent.ACTION_MOVE:
int moveX = (int) ev.getX();
int diff = Math.abs(downX - moveX);
// int dirf = Math.abs(downRX + moveX);
Log.i(TAG, "diff的位置:" + diff );
if (diff >touchSlop) {
return true;
}
// else if(dirf < touchSlop) {
// return true;
// }
break;
case MotionEvent.ACTION_UP:
break;
}
return super.onInterceptTouchEvent(ev);


}
//事件触摸事件
@Override
public boolean onTouchEvent(MotionEvent event) {
int scrollX;


switch (event.getAction()) {
//获取向右滑动的x轴的位置
case MotionEvent.ACTION_DOWN:
downX = (int) event.getX();
Log.i(TAG, "onTouchEvent的 downX位置:" + downX );
break;
case MotionEvent.ACTION_MOVE:
int moveX = (int) event.getX();
int deltaX = downX - moveX;
// 判断给定当前的增量移动后, 是否能够超出边界.
scrollX = getScrollX() + deltaX;
if(scrollX < -getChildAt(0).getMeasuredWidth()) {
// 当前超出了左边界, 应该设置为在菜单的左边界位置上.
scrollTo(-getChildAt(0).getMeasuredWidth(), 0);
} else if(scrollX > 0) {
// 当前超出了右边界, 应该设置为0
scrollTo(0, 0);
} else {
scrollBy(deltaX, 0);
}


downX = moveX;
break;
case MotionEvent.ACTION_UP:
// 获取菜单宽度的一半
int center = -getChildAt(0).getMeasuredWidth() / 2;
scrollX = getScrollX(); // 当前屏幕左上角的值


if(scrollX >center) {


currentScreen = SCREEN_MAIN;
} else {


currentScreen = SCREEN_MENU;
}
switchScreen();




break;
default:
break;
}
return true;








}
// teacher
private void switchScreen() {
int startX = getScrollX(); // 开始的位置
int dx = 0; // 增量值 = 目的地位置 - 开始的位置;
if(currentScreen == SCREEN_MAIN) {
dx = 0 - startX;
} else if(currentScreen == SCREEN_MENU) {
dx = -getChildAt(0).getMeasuredWidth() - startX;
}


int duration = Math.abs(dx) * 10;
if(duration > 1000) {
duration = 1000;
}
scroller.startScroll(startX, 0, dx, 0, duration);


// 刷新当前控件, 会引起onDraw方法的调用.
invalidate();
}
@Override
public void computeScroll() {
// 判断是否已经完成距离拆分操作
if (scroller.computeScrollOffset()) {
// 获取一小段移动的距离
int currX = scroller.getCurrX();
// 移动一小段距离


scrollTo(currX,0);
// 进行下一次移动距离操作
invalidate();
}




}
// 是否显示菜单


public boolean isShowMenu() {
return currentScreen == SCREEN_MENU;
}


// 隐藏菜单


public void hideMenu() {
currentScreen = SCREEN_MAIN;
switchScreen();
}


// 显示菜单


public void showMenu() {
currentScreen = SCREEN_MENU;
switchScreen();
}
}


6.  MainActivity.jave:

package com.example.slidingmenu;


import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;


import com.example.slidingmenu.view.SlidingMenu;




public class MainActivity extends Activity implements OnClickListener{
private SlidingMenu mSlidingMenu;


@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
initView();
}


private void initView() {


ImageView mBack = (ImageView) findViewById(R.id.back);


mSlidingMenu = (SlidingMenu) findViewById(R.id.myslidingmenu);


mBack.setOnClickListener(this);

}
public void showText(View view){
TextView textView = (TextView)view;
//toast显示文本
Toast.makeText(this, textView.getText(), 0).show();
}


@Override
public void onClick(View arg0) {
// 判断当前是哪一个屏幕
boolean isShowMenu = mSlidingMenu.isShowMenu();


if(isShowMenu) {
// 是菜单界面, 切换到主界面
mSlidingMenu.hideMenu();
} else {
// 是主界面, 应该把菜单显示出来
mSlidingMenu.showMenu();
}
}


}



主要就是想记录一下,免得忘记了.....。















  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值