我參考了這篇文章,我將它改了一下:
可動(dòng)態(tài)布局的Android抽屜之基礎(chǔ)
工程中需要這樣的效果,左邊和右邊的Panel可以打開(kāi)關(guān)閉:
我把左邊和右邊的Panel封裝成2個(gè)類了。這里要特別注意,抽屜是需要“handler”的,我這里可以把任何View都看成“handler”,使用setBindView(View bindView)方法進(jìn)行綁定“handler”。這樣做的好處是“把手”可以獨(dú)立于抽屜,可以任意控制把手的位置,而不需要把手跟著抽屜移動(dòng)!
先看左邊的Panel:
右邊的Panel,需要注意構(gòu)造函數(shù)多了viewBeside參數(shù):
使用方法:
main.xml:
可動(dòng)態(tài)布局的Android抽屜之基礎(chǔ)
工程中需要這樣的效果,左邊和右邊的Panel可以打開(kāi)關(guān)閉:

我把左邊和右邊的Panel封裝成2個(gè)類了。這里要特別注意,抽屜是需要“handler”的,我這里可以把任何View都看成“handler”,使用setBindView(View bindView)方法進(jìn)行綁定“handler”。這樣做的好處是“把手”可以獨(dú)立于抽屜,可以任意控制把手的位置,而不需要把手跟著抽屜移動(dòng)!
先看左邊的Panel:
import android.content.Context; import android.os.AsyncTask; import android.view.View; import android.widget.LinearLayout; public class LeftPanel extends LinearLayout{ /**每次自動(dòng)展開(kāi)/收縮的范圍*/ private final static int SPEED=20; private int MAX_WIDTH=0; private Context mContext; public LeftPanel(Context context,int width,int height) { super(context); this.mContext=context; //設(shè)置Panel本身的屬性 LayoutParams lp=new LayoutParams(width, height); lp.leftMargin=-lp.width; MAX_WIDTH=Math.abs(lp.leftMargin); this.setLayoutParams(lp); } /** * * @param context * @param width * @param height * @param bindView * @param contentView */ public LeftPanel(Context context,int width,int height,View bindView,View contentView) { this(context,width,height); setBindView(bindView); setContentView(contentView); } /** * 把View放在Panel中 * @param v */ public void setContentView(View v){ this.addView(v); } /** * 綁定觸發(fā)動(dòng)畫的View * @param bindView */ public void setBindView(View bindView){ bindView.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v) { LayoutParams lp = (LayoutParams) getLayoutParams(); if (lp.leftMargin < 0)// CLOSE的狀態(tài) new AsynMove().execute(new Integer[] { SPEED });// 正數(shù)展開(kāi) else if (lp.leftMargin >= 0)// OPEN的狀態(tài) new AsynMove().execute(new Integer[] { -SPEED });// 負(fù)數(shù)收縮 } }); } class AsynMove extends AsyncTask<Integer, Integer, Void> { @Override protected Void doInBackground(Integer... params) { int times; if (MAX_WIDTH % Math.abs(params[0]) == 0)// 整除 times = MAX_WIDTH / Math.abs(params[0]); else times = MAX_WIDTH / Math.abs(params[0]) + 1;// 有余數(shù) for (int i = 0; i < times; i++) { publishProgress(params); try { Thread.sleep(Math.abs(params[0])); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return null; } @Override protected void onProgressUpdate(Integer... params) { LayoutParams lp = (LayoutParams)getLayoutParams(); if (params[0] < 0){//關(guān)閉 lp.leftMargin = Math.max(lp.leftMargin + params[0],-MAX_WIDTH); } else{//打開(kāi) lp.leftMargin = Math.min(lp.leftMargin + params[0],MAX_WIDTH); } if(lp.leftMargin==0 && onPanelStatusChangedListener!=null){//展開(kāi)之后 onPanelStatusChangedListener.onPanelOpened(LeftPanel.this);//調(diào)用OPEN回調(diào)函數(shù) } else if(lp.leftMargin==-MAX_WIDTH && onPanelStatusChangedListener!=null){//收縮之后 onPanelStatusChangedListener.onPanelClosed(LeftPanel.this);//調(diào)用CLOSE回調(diào)函數(shù) } setLayoutParams(lp); } } public interface OnPanelStatusChangedListener{ void onPanelOpened(LeftPanel panel); void onPanelClosed(LeftPanel panel); } private OnPanelStatusChangedListener onPanelStatusChangedListener; public void setOnPanelStatusChangedListener(OnPanelStatusChangedListener onPanelStatusChangedListener){ this.onPanelStatusChangedListener=onPanelStatusChangedListener; } }
右邊的Panel,需要注意構(gòu)造函數(shù)多了viewBeside參數(shù):
import android.content.Context; import android.os.AsyncTask; import android.view.View; import android.widget.LinearLayout; public class RightPanel extends LinearLayout{ /**每次自動(dòng)展開(kāi)/收縮的范圍*/ private final static int SPEED=20; private int MAX_WIDTH=0; private Context mContext; /** * viewBeside自動(dòng)布局以適應(yīng)Panel展開(kāi)/收縮的空間變化 * */ public RightPanel(Context context,View viewBeside,int width,int height) { super(context); this.mContext=context; //必須改變Panel左側(cè)組件的weight屬性 LayoutParams p=(LayoutParams) viewBeside.getLayoutParams(); p.weight=1;//支持?jǐn)D壓 viewBeside.setLayoutParams(p); //設(shè)置Panel本身的屬性 LayoutParams lp=new LayoutParams(width, height); lp.rightMargin=-lp.width; MAX_WIDTH=Math.abs(lp.rightMargin); this.setLayoutParams(lp); } /** * * @param context * @param otherView * @param width * @param height * @param bindView * @param contentView */ public RightPanel(Context context,View viewBeside,int width,int height,View bindView,View contentView) { this(context,viewBeside,width,height); setBindView(bindView); setContentView(contentView); } /** * 把View放在Panel中 * @param v */ public void setContentView(View v){ this.addView(v); } /** * 綁定觸發(fā)動(dòng)畫的View * @param bindView */ public void setBindView(View bindView){ bindView.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v) { LayoutParams lp = (LayoutParams) getLayoutParams(); if (lp.rightMargin < 0)// CLOSE的狀態(tài) new AsynMove().execute(new Integer[] { SPEED });// 正數(shù)展開(kāi) else if (lp.rightMargin >= 0)// OPEN的狀態(tài) new AsynMove().execute(new Integer[] { -SPEED });// 負(fù)數(shù)收縮 } }); } class AsynMove extends AsyncTask<Integer, Integer, Void> { @Override protected Void doInBackground(Integer... params) { int times; if (MAX_WIDTH % Math.abs(params[0]) == 0)// 整除 times = MAX_WIDTH / Math.abs(params[0]); else times = MAX_WIDTH / Math.abs(params[0]) + 1;// 有余數(shù) for (int i = 0; i < times; i++) { publishProgress(params); try { Thread.sleep(Math.abs(params[0])); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return null; } @Override protected void onProgressUpdate(Integer... params) { LayoutParams lp = (LayoutParams)getLayoutParams(); if (params[0] < 0) lp.rightMargin = Math.max(lp.rightMargin + params[0], -MAX_WIDTH); else lp.rightMargin = Math.min(lp.rightMargin + params[0], 0); if(lp.rightMargin==0 && onPanelStatusChangedListener!=null){//展開(kāi)之后 onPanelStatusChangedListener.onPanelOpened(RightPanel.this);//調(diào)用OPEN回調(diào)函數(shù) } else if(lp.rightMargin==-MAX_WIDTH && onPanelStatusChangedListener!=null){//收縮之后 onPanelStatusChangedListener.onPanelClosed(RightPanel.this);//調(diào)用CLOSE回調(diào)函數(shù) } setLayoutParams(lp); } } public interface OnPanelStatusChangedListener{ void onPanelOpened(RightPanel panel); void onPanelClosed(RightPanel panel); } private OnPanelStatusChangedListener onPanelStatusChangedListener; public void setOnPanelStatusChangedListener(OnPanelStatusChangedListener onPanelStatusChangedListener){ this.onPanelStatusChangedListener=onPanelStatusChangedListener; } }
使用方法:
import android.app.Activity; import android.graphics.Color; import android.os.Bundle; import android.util.Log; import android.view.Gravity; import android.view.View; import android.widget.Button; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.LinearLayout.LayoutParams; public class App extends Activity { public LeftPanel leftPanel; public RightPanel rightPanel; public LinearLayout container; public Button btn_0,btn_1; private View tv; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); container=(LinearLayout)findViewById(R.id.container); btn_0 = (Button) findViewById(R.id.btn_0); btn_1 = (Button) findViewById(R.id.btn_1); tv = findViewById(R.id.tv); //新建測(cè)試組件 TextView content0=new TextView(this); content0.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT)); content0.setText("左邊的panel"); content0.setGravity(Gravity.CENTER); content0.setTextColor(Color.RED); content0.setBackgroundColor(Color.WHITE); //新建測(cè)試組件 TextView content1=new TextView(this); content1.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT)); content1.setText("右邊的panel"); content1.setGravity(Gravity.CENTER); content1.setTextColor(Color.RED); content1.setBackgroundColor(Color.WHITE); leftPanel=new LeftPanel(this,120,LayoutParams.FILL_PARENT); leftPanel.setBindView(btn_0); leftPanel.setContentView(content0); leftPanel.setOnPanelStatusChangedListener(new LeftPanel.OnPanelStatusChangedListener() { @Override public void onPanelOpened(LeftPanel panel) { // TODO Auto-generated method stub Log.i("tag", "======onPanelOpened======="); } @Override public void onPanelClosed(LeftPanel panel) { // TODO Auto-generated method stub Log.i("tag", "======onPanelClosed======="); } }); container.addView(leftPanel,0);//加入Panel控件 // rightPanel=new RightPanel(this,tv,120,LayoutParams.FILL_PARENT); rightPanel.setBindView(btn_1); rightPanel.setContentView(content1); rightPanel.setOnPanelStatusChangedListener(new RightPanel.OnPanelStatusChangedListener() { @Override public void onPanelOpened(RightPanel panel) { // TODO Auto-generated method stub Log.i("tag", "======onPanelOpened======="); } @Override public void onPanelClosed(RightPanel panel) { // TODO Auto-generated method stub Log.i("tag", "======onPanelClosed======="); } }); container.addView(rightPanel);//加入Panel控件 } }
main.xml:
<?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:orientation="vertical" > <LinearLayout android:id="@+id/container" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal" android:layout_weight="1" > <TextView android:id="@+id/tv" android:layout_width="fill_parent" android:layout_height="fill_parent" android:gravity="center" android:text="hello,squeeze me." /> </LinearLayout> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:gravity="center" > <Button android:id="@+id/btn_0" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="left" /> <Button android:id="@+id/btn_1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="right" /> </LinearLayout> </LinearLayout>
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元
