自定义侧滑组件+自定义属性
2016-06-24 01:21
387 查看
继承HorizontalScrollView,通过添加各种方法,自定义实现各种侧滑效果 先看xml布局文件 <?xml version="1.0" encoding="utf-8"?> <com.example.administrator.slidingmenu.widget.SlidingMenu 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" xmlns:app="http://schemas.android.com/apk/res-auto" <!--自定义属性的赋值--> app:left_off_width="300" tools:context="com.example.administrator.slidingmenu.MainActivity"> <com.example.administrator.slidingmenu.widget.OrdetDrawLinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal"> <LinearLayout android:id="@+id/teach_left_menu" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:background="@color/colorAccent" > <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:text="左侧菜单" /> </LinearLayout> <LinearLayout android:id="@+id/teach_main_content" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:orientation="vertical" android:background="@color/colorPrimary"> <ImageView android:layout_width="200dp" android:layout_height="200dp" android:src="@mipmap/ic_launcher" /> </LinearLayout> </com.example.administrator.slidingmenu.widget.OrdetDrawLinearLayout> </com.example.administrator.slidingmenu.widget.SlidingMenu>
再看Java代码。自定义侧滑组件的类SlidingMenu继承于HorizoltalScrollView
package com.example.administrator.slidingmenu.widget;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.HorizontalScrollView;
import android.widget.LinearLayout;
import com.example.administrator.slidingmenu.R;
/**
*
* ViewGroup 绘制流程
* onMeasure
* onLayout
* onDraw
*
*
*自定义属性
* 1在value下创建attrs,在其中使用<declare-styleable标签声明我们自己要为哪个View设置属性
* 2在自定义属性中创建自己的属性,指定name和format
* 2在我们View的构造函数中,使用TypeArray进行属性的加载,使用完成要注意回收
* 4对我们获取的值进行使用,在xml布局中使用自定义属性
*
* Created by Administrator on 2016/6/16.
*/
public class SlidingMenu extends HorizontalScrollView{
private static final String TAG = SlidingMenu.class.getSimpleName();
private View mLeftMenu;//左侧的侧滑布局
private View mContent;//主内容布局
private int mScreenWidth;//屏幕宽度
private int leftMenuWidthOff;//当左侧菜单划出的时候屏幕的剩余宽度
private static final int MENU_DEFAULT_WIDTH_OFF=150;//指定默认值,没有更改时就是这个值
private int leftMenuWidth;//左侧菜单的宽度
private boolean isMeasure;//布局测量的标记位
private int leftMenuHaftWidth;//左侧菜单宽度的一半
public SlidingMenu(Context context) {
this(context, null);
}
/**
* 使用Inflate进来的View走两个参数的构造
* @param context
* @param attrs
*/
public SlidingMenu(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public SlidingMenu(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
//获取屏幕宽度
mScreenWidth=getResources().getDisplayMetrics().widthPixels;
//自定义的所有属性
TypedArray typedArray = context.getTheme().obtainStyledAttributes(attrs, R.styleable.SlidingMenr, defStyleAttr, 0);
leftMenuWidthOff=typedArray.getInt(R.styleable.SlidingMenr_left_off_width, MENU_DEFAULT_WIDTH_OFF);
//使用完成要回收
typedArray.recycle();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (!isMeasure) {
//滑动布局中的唯一的Child
LinearLayout single = (LinearLayout) getChildAt(0);
//获取左侧菜单
mLeftMenu = single.getChildAt(0);
//获取中间的内容部分
mContent = single.getChildAt(1);
//左侧的菜单宽度赋值
leftMenuWidth = mScreenWidth - leftMenuWidthOff;
//左侧菜单的一半
// leftMenuHaftWidth=leftMenuWidth/2;
leftMenuHaftWidth=leftMenuWidth >> 1;
//设置左边Menu的宽度
mLeftMenu.getLayoutParams().width = leftMenuWidth;
//设置主内容区域的宽度
mContent.getLayoutParams().width=mScreenWidth;
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
if(changed){
//粗暴滚动
scrollTo(leftMenuWidth, 0);
isMeasure=true;
}
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_UP:
int scrollX = getScrollX();
Log.e(TAG, "onTouchEvent"+scrollX);
//滑动距离大于左侧菜单的一半
if (scrollX>leftMenuHaftWidth) {
//显示主内容区
//平滑滚动
smoothScrollTo(leftMenuWidth, 0);
}else {
//显示左侧菜单
smoothScrollTo(0,0);
}
return true;
}
return super.onTouchEvent(ev);
}
//可以在onScrollChanged方法中添加各种动画
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
Log.e(TAG, "onScrollChanged: -->" + l + "---" + t);
//测试手机宽度1080,左侧菜单减少宽度150,上一步向左滚动了leftMenuWidth,所以这里初始l为1080-150=930。向左滑动l为正值
//效果:当向右滑动时,左侧菜单同时向右平移,感觉左侧菜单一直在右侧的底部
//即菜单被掩盖
// mLeftMenu.setTranslationX(l);
//主内容被掩盖。
mContent.setTranslationX(l-leftMenuWidth);
}
}
当执行上面onScrollChanged方法
//主内容被掩盖。 mContent.setTranslationX(l-leftMenuWidth);
的方法的时候,会出现bug,导致内容页面完全覆盖侧滑页面,所以执行下面自定义方法,改变其Child的绘制顺序
package com.example.administrator.slidingmenu.widget; import android.content.Context; import android.util.AttributeSet; import android.widget.LinearLayout; /** * 更改View绘制的顺序 * 重写getChildDrawingOrder * 设置Child绘制顺序可以更改(启用绘制顺序) * * * Created by Administrator on 2016/6/16. */ public class OrdetDrawLinearLayout extends LinearLayout { public OrdetDrawLinearLayout(Context context) { this(context, null); } public OrdetDrawLinearLayout(Context context, AttributeSet attrs) { this(context, attrs, 0); } public OrdetDrawLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); setChildrenDrawingOrderEnabled(true); } <span style="font-family:KaiTi_GB2312;">//改变其Child组件的绘制顺序</span> @Override protected int getChildDrawingOrder(int childCount, int i) { switch (i) { case 1: return 0; case 0: return 1; } return super.getChildDrawingOrder(childCount, i); } }
自定义属性:在main/ res/ values 文件夹下,建attrs文件,里面写下面代码
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="SlidingMenr">
<attr name="left_off_width" format="integer"/>
</declare-styleable>
</resources>
相关文章推荐
- autotools的使用
- OpenGL深入探索——阴影贴图(二)
- Leetcode Find Median from Data Stream
- 获取当前主题设置的属性
- 趣味程序设计_爱因斯坦的数学题(中剩)
- 160623dyld: Library not loaded:
- 开发错误记录11:git报错 fatal:open /dev/null or dup failed: No such file or directory
- 问题 G: 整数连接
- 《Java数据结构与算法》笔记-CH5-链表-1单链表
- Mysql引擎介绍
- Mysql优势和特点
- H5、React Native、Native应用对比分析
- 新概念英语
- literature文学评析
- 3D 电影欣赏
- 有权并查集,Poj(1988)
- 电影评析
- Java之JSP和Servlet基础知识。
- 家庭网络方案分享
- 作者:唐欢----感悟和经验