大家好,我是极客范的本期栏目编辑小友,现在为大家讲解可动态布局的Android抽屉之完整篇问题。
之前已经介绍过,《Android提高第十九篇之“多方向”抽屉》在抽屉组件不与周围组件压缩时效果更好(周围组件布局不变),但如果周围组件需要压缩,使用起来就不美观了。
下图。在左右挤压的情况下,抽屉先挤压周围的组件一次,然后通过动画效果展开/收缩。这种方法的优点是快速简单,缺点是如果挤压范围太大,效果就比较钝。
本文实现的自定义抽屉组件主要是提升压缩效果,逐步压缩周围组件,让过渡效果更加美观。下图。
本文实现的鸽笼原理是酱紫色:
1.抽屉组件主要在屏幕的不可见区域,把手在屏幕边缘的可见区域。也就是抽屉。rightMargin=-XXX句柄。宽度。
2.将周围的组件指定为可挤压的,即layout params . weight=1;当然,用户也可以指定多个视图。
3.使用AsyncTask实现弹出/收缩动画。弹出:抽屉。右边距=XX,收缩:抽屉。rightMargin-=XX。
综上所述,本文中的定制抽屉虽然对挤压周围组件有过渡作用,但消耗的资源较多,读者可以根据不同情况考虑使用。
这篇文章的源代码可以从http://download.csdn.net/detail/hellogv/3615686.下载
接下来,发布本文的所有源代码:
Main.xml源代码:
[html]查看plaincopyprint?
《span style=“font-family:Comic Sans MS;font-size:18px;”》 《?xml version=“1.0” encoding=“utf-8”?》
《线性布局xmlns:android安卓=》http://schemas.android.com/apk/res/android"
Android : layout _ width="fill _ parent"Android : layout _ height="fill _ parent"
android:id="@ id/container""
《GridView AnDroid : id="@ id/GridView"AnDroid : layout _ width="fill _ parent"
Android : layout _ height="fill _ parent"Android : num columns="auto _ fit"
安卓:垂直空间=“10dp”安卓:重心=“中心”
andrid : column width="50 dip"andrid : horizontal spacing="10 dip"/"
《/LinearLayout》 《/span》
《span style=“font-family:Comic Sans MS;font-size:18px;”》 《?xml version=“1.0” encoding=“utf-8”?》
《线性布局xmlns:android安卓=》http://schemas.android.com/apk/res/android"
Android : layout _ width="fill _ parent"Android : layout _ height="fill _ parent"
android:id="@ id/container""
《GridView AnDroid : id="@ id/GridView"AnDroid : layout _ width="fill _ parent"
Android : layout _ height="fill _ parent"Android : num columns="auto _ fit"
安卓:垂直空间=“10dp”安卓:gra
vity=“center”android:columnWidth=“50dip” android:horizontalSpacing=“10dip” /》
《/LinearLayout》《/span》
GridView的Item.xml的源码:
[html] view plaincopyprint?
《span style=“font-family:Comic Sans MS;font-size:18px;”》《?xml version=“1.0” encoding=“utf-8”?》
《RelaTIveLayout xmlns:android=“http://schemas.android.com/apk/res/android”
android:layout_height=“wrap_content” android:paddingBottom=“4dip”
android:layout_width=“fill_parent”》
《ImageView android:layout_height=“wrap_content” android:id=“@+id/ItemImage”
android:layout_width=“wrap_content” android:layout_centerHorizontal=“true”》
《/ImageView》
《TextView android:layout_width=“wrap_content”
android:layout_below=“@+id/ItemImage” android:layout_height=“wrap_content”
android:text=“TextView01” android:layout_centerHorizontal=“true”
android:id=“@+id/ItemText”》
《/TextView》
《/RelaTIveLayout》 《/span》
《span style=“font-family:Comic Sans MS;font-size:18px;”》《?xml version=“1.0” encoding=“utf-8”?》
《RelativeLayout xmlns:android=“http://schemas.android.com/apk/res/android”
android:layout_height=“wrap_content” android:paddingBottom=“4dip”
android:layout_width=“fill_parent”》
《ImageView android:layout_height=“wrap_content” android:id=“@+id/ItemImage”
android:layout_width=“wrap_content” android:layout_centerHorizontal=“true”》
《/ImageView》
《TextView android:layout_width=“wrap_content”
android:layout_below=“@+id/ItemImage” android:layout_height=“wrap_content”
android:text=“TextView01” android:layout_centerHorizontal=“true”
android:id=“@+id/ItemText”》
《/TextView》
《/RelativeLayout》 《/span》
Panel.java是本文核心,抽屉组件的源码,这个抽屉只实现了从右往左的弹出/从左往右的收缩,读者可以根据自己的需要修改源码来改变抽屉动作的方向:
[java] view plaincopyprint?
《span style=“font-family:Comic Sans MS;font-size:18px;”》public class Panel extends LinearLayout{
public interface PanelClosedEvent {
void onPanelClosed(View panel);
}
public interface PanelOpenedEvent {
void onPanelOpened(View panel);
}
/**Handle的宽度,与Panel等高*/
private final static int HANDLE_WIDTH=30;
/**每次自动展开/收缩的范围*/
private final static int MOVE_WIDTH=20;
private Button btnHandle;
private LinearLayout panelContainer;
private int mRightMargin=0;
private Context mContext;
private PanelClosedEvent panelClosedEvent=null;
private PanelOpenedEvent panelOpenedEvent=null;
/**
* otherView自动布局以适应Panel展开/收缩的空间变化
* @author GV
*
*/
public Panel(Context context,View otherView,int width,int height) {
super(context);
this.mContext=context;
//改变Panel附近组件的属性
LayoutParams otherLP=(LayoutParams) otherView.getLayoutParams();
otherLP.weight=1;//支持压挤
otherView.setLayoutParams(otherLP);
//设置Panel本身的属性
LayoutParams lp=new LayoutParams(width, height);
lp.rightMargin=-lp.width+HANDLE_WIDTH;//Panel的Container在屏幕不可视区域,Handle在可视区域
mRightMargin=Math.abs(lp.rightMargin);
this.setLayoutParams(lp);
this.setOrientation(LinearLayout.HORIZONTAL);
//设置Handle的属性
btnHandle=new Button(context);
btnHandle.setLayoutParams(new LayoutParams(HANDLE_WIDTH,height));
btnHandle.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View arg0) {
LayoutParams lp = (LayoutParams) Panel.this.getLayoutParams();
if (lp.rightMargin 《 0)// CLOSE的状态
new AsynMove().execute(new Integer[] { MOVE_WIDTH });// 正数展开
else if (lp.rightMargin 》= 0)// OPEN的状态
new AsynMove().execute(new Integer[] { -MOVE_WIDTH });// 负数收缩
}
});
//btnHandle.setOnTouchListener(HandleTouchEvent);
this.addView(btnHandle);
//设置Container的属性
panelContainer=new LinearLayout(context);
panelContainer.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT));
this.addView(panelContainer);
}
/**
以前曾经介绍过《Android提高第十九篇之“多方向”抽屉》,当这个抽屉组件不与周围组件发生压挤的情况下(周围组件布局不变),是比较好使的,但是如果需要对周围组件挤压,则用起来欠缺美观了。
如下图。在对周围压挤的情况下,抽屉是先把周围的组件一次性压挤,再通过动画效果展开/收缩的,这种做法的好处是快速简单,坏处是如果挤压范围过大,则效果生硬。
本文实现的自定义抽屉组件,主要针对这种压挤效果做出改良,渐进式压挤周围组件,使得过渡效果更加美观。如下图。
本文实现的抽屉原理是酱紫:
1.抽屉组件主要在屏幕不可视区域,手柄在屏幕边缘的可视区域。即 抽屉.rightMargin=-XXX + 手柄.width
2.指定一个周围组件为可压挤,即LayoutParams.weight=1;当然用户也可以指定多个View.
3.使用AsyncTask来实现弹出/收缩的动画,弹出:抽屉.rightMargin+=XX,收缩:抽屉.rightMargin-=XX
总结,本文的自定义抽屉虽然对压挤周围组件有过渡效果,但是比较耗资源,读者可以针对不同的情况考虑使用。
本文的源码可以到http://download.csdn.net/detail/hellogv/3615686 下载。
接下来贴出本文全部源代码:
main.xml的源码:
[html] view plaincopyprint?
《span style=“font-family:Comic Sans MS;font-size:18px;”》《?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/container”》
《GridView android:id=“@+id/gridview” android:layout_width=“fill_parent”
android:layout_height=“fill_parent” android:numColumns=“auto_fit”
android:verTIcalSpacing=“10dp” android:gravity=“center”
android:columnWidth=“50dip” android:horizontalSpacing=“10dip” /》
《/LinearLayout》《/span》
《span style=“font-family:Comic Sans MS;font-size:18px;”》《?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/container”》
《GridView android:id=“@+id/gridview” android:layout_width=“fill_parent”
android:layout_height=“fill_parent” android:numColumns=“auto_fit”
android:verTIcalSpacing=“10dp” android:gravity=“center”
android:columnWidth=“50dip” android:horizontalSpacing=“10dip” /》
《/LinearLayout》《/span》
GridView的Item.xml的源码:
[html] view plaincopyprint?
《span style=“font-family:Comic Sans MS;font-size:18px;”》《?xml version=“1.0” encoding=“utf-8”?》
《RelaTIveLayout xmlns:android=“http://schemas.android.com/apk/res/android”
android:layout_height=“wrap_content” android:paddingBottom=“4dip”
android:layout_width=“fill_parent”》
《ImageView android:layout_height=“wrap_content” android:id=“@+id/ItemImage”
android:layout_width=“wrap_content” android:layout_centerHorizontal=“true”》
《/ImageView》
《TextView android:layout_width=“wrap_content”
android:layout_below=“@+id/ItemImage” android:layout_height=“wrap_content”
android:text=“TextView01” android:layout_centerHorizontal=“true”
android:id=“@+id/ItemText”》
《/TextView》
《/RelaTIveLayout》 《/span》
《span style=“font-family:Comic Sans MS;font-size:18px;”》《?xml version=“1.0” encoding=“utf-8”?》
《RelativeLayout xmlns:android=“http://schemas.android.com/apk/res/android”
android:layout_height=“wrap_content” android:paddingBottom=“4dip”
android:layout_width=“fill_parent”》
《ImageView android:layout_height=“wrap_content” android:id=“@+id/ItemImage”
android:layout_width=“wrap_content” android:layout_centerHorizontal=“true”》
《/ImageView》
《TextView android:layout_width=“wrap_content”
android:layout_below=“@+id/ItemImage” android:layout_height=“wrap_content”
android:text=“TextView01” android:layout_centerHorizontal=“true”
android:id=“@+id/ItemText”》
《/TextView》
《/RelativeLayout》 《/span》
Panel.java是本文核心,抽屉组件的源码,这个抽屉只实现了从右往左的弹出/从左往右的收缩,读者可以根据自己的需要修改源码来改变抽屉动作的方向:
[java] view plaincopyprint?
《span style=“font-family:Comic Sans MS;font-size:18px;”》public class Panel extends LinearLayout{
public interface PanelClosedEvent {
void onPanelClosed(View panel);
}
public interface PanelOpenedEvent {
void onPanelOpened(View panel);
}
/**Handle的宽度,与Panel等高*/
private final static int HANDLE_WIDTH=30;
/**每次自动展开/收缩的范围*/
private final static int MOVE_WIDTH=20;
private Button btnHandle;
private LinearLayout panelContainer;
private int mRightMargin=0;
private Context mContext;
private PanelClosedEvent panelClosedEvent=null;
private PanelOpenedEvent panelOpenedEvent=null;
/**
* otherView自动布局以适应Panel展开/收缩的空间变化
* @author GV
*
*/
public Panel(Context context,View otherView,int width,int height) {
super(context);
this.mContext=context;
//改变Panel附近组件的属性
LayoutParams otherLP=(LayoutParams) otherView.getLayoutParams();
otherLP.weight=1;//支持压挤
otherView.setLayoutParams(otherLP);
//设置Panel本身的属性
LayoutParams lp=new LayoutParams(width, height);
lp.rightMargin=-lp.width+HANDLE_WIDTH;//Panel的Container在屏幕不可视区域,Handle在可视区域
mRightMargin=Math.abs(lp.rightMargin);
this.setLayoutParams(lp);
this.setOrientation(LinearLayout.HORIZONTAL);
//设置Handle的属性
btnHandle=new Button(context);
btnHandle.setLayoutParams(new LayoutParams(HANDLE_WIDTH,height));
btnHandle.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View arg0) {
LayoutParams lp = (LayoutParams) Panel.this.getLayoutParams();
if (lp.rightMargin 《 0)// CLOSE的状态
new AsynMove().execute(new Integer[] { MOVE_WIDTH });// 正数展开
else if (lp.rightMargin 》= 0)// OPEN的状态
new AsynMove().execute(new Integer[] { -MOVE_WIDTH });// 负数收缩
}
});
//btnHandle.setOnTouchListener(HandleTouchEvent);
this.addView(btnHandle);
//设置Container的属性
panelContainer=new LinearLayout(context);
panelContainer.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT));
this.addView(panelContainer);
}
/**
技术专区 睿赛德科技喜迁新址 ,RT-Thread进入新的加速发展阶段可靠性高、控制灵活、低功耗可调速风扇散热系统安防监控摄像头LED驱动解决方案如何定制嵌入式Linux发行版基于SoC实现的数据采集系统详解