您的位置首页>硬件>

可动态布局的Android抽屉之完整篇

导读大家好,我是极客范的本期栏目编辑小友,现在为大家讲解可动态布局的Android抽屉之完整篇问题。之前已经介绍过,《Android提高第十九篇之“

大家好,我是极客范的本期栏目编辑小友,现在为大家讲解可动态布局的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实现的数据采集系统详解
郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。