正在自学Android,今天学习慕课上的教程进行侧滑菜单的实现.
慕课网原地址:http://www.imooc.com/learn/211
一、开始界面如左图所示,手指移动后改为右图
二、代码分析:
首先.先做个一个自定义xml文件作为自定义view的布局
RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/listView"
android:entries="@array/set"/>
</LinearLayout>
</RelativeLayout>
接着,要自定义一个Menu,要让其继承
HorizontalScrollView,我们要重写 onMeasure(), onLayout()以及onTouchEvent()三个方法。代码如下
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.HorizontalScrollView;
import android.widget.LinearLayout;
/**
* Created by linzhengle on 2015/12/1.
*/
public class Menu extends HorizontalScrollView {
private LinearLayout mWapper;
private ViewGroup mMenu;
private ViewGroup mContent;
//滑动惨淡的宽度,手机的宽度
private int mMenuWidth;
private int mScreeenWidth;
private int mMenuRightPadding = 50;
private boolean once = false;
public Menu(Context context){
this(context,null);
}
public Menu(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
/*
使用自定义属性
*/
public Menu(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs,defStyle);
//获取定义的属性
TypedArray a = context.getTheme().obtainStyledAttributes(attrs,R.styleable.SiMenu,defStyle,0);
int n = a.getIndexCount();
for(int i = 0; i < n; i++){
int attr = a.getIndex(i);
switch (attr)
{
case R.styleable.SiMenu_rightPadding :
mMenuRightPadding = a.getDimensionPixelSize(attr,(int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,50,context.getResources().getDisplayMetrics()));
break;
}
}
a.recycle();
WindowManager wm =(WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics outMetrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(outMetrics);
mScreeenWidth = outMetrics.widthPixels;
//把dp转为px
// mMenuRightPadding = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,50,context.getResources().getDisplayMetrics());
}
/*
设置子view 的宽和高,以及自变量的宽高
*/
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec ){
if(!once){
mWapper = (LinearLayout)getChildAt(0);
mMenu = (ViewGroup) mWapper.getChildAt(0);
mContent = (ViewGroup) mWapper.getChildAt(1);
mMenuWidth = mMenu.getLayoutParams().width = mScreeenWidth - mMenuRightPadding;
mContent.getLayoutParams().width = mScreeenWidth;
once = true;
}
super.onMeasure(widthMeasureSpec,heightMeasureSpec);
}
/**
* 通过设置偏移量对menu进行隐藏
*/
public void onLayout(boolean changed, int i, int j, int r, int b)
{
super.onLayout(changed, i, j, r, b);
if (changed)
this.scrollTo(mMenuWidth, 0);
}
public boolean onTouchEvent(MotionEvent event){
int action = event.getAction();
switch (action)
{
case MotionEvent.ACTION_UP:
int scrollX = getScrollX();
if(scrollX >= mMenuWidth / 2){
this.smoothScrollTo(mMenuWidth,0);
}else{
this.smoothScrollTo(0,0);
}
return true;
}
return super.onTouchEvent(event);
}
}
紧接着是主程序的布局:
RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:hyman = "http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.linzhengle.qq50.MainActivity">
<com.example.linzhengle.qq50.Menu
android:layout_width="match_parent"
android:layout_height="match_parent"
hyman:rightPadding="100dp"
android:id="@+id/linze">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="@layout/hh"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="@color/colorAccent"></LinearLayout>
</LinearLayout>
</com.example.linzhengle.qq50.Menu>
</RelativeLayout>
主Activity程序:
import android.content.Context;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
Context context;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
三:分析:
主要是用HorizontalScrollView来进行新的自定义文件,在menu类中,要先使用构造器,来获取屏幕宽度,以及获取自定义的属性.而onMeasure()方法是为了设置子View的高宽和自变量的高宽.smoothScrollTo是Google官方提供的方法,主要用于在移动时动画的改变.另外使用自定义View的时候要用到完整的包名加类名.