android之自定义Panel

这篇博客介绍了如何在Android中创建一个自定义Panel,点击Panel按钮后,动态显示测试1/2/3按钮,并能挤压其他布局。实现过程参考了网络资源。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这个例子主要是实现上面这样的效果,点击Panel按钮,实现测试1/2/3按钮动态显示并挤压其他布局(实现过程参照网上的一些资料,如有侵权,请告之)

package com.android.PanelDemo;

import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;
import android.view.View;
import android.widget.LinearLayout;

public class Panel extends LinearLayout{
	private static final String TAG = "Panel";
	private OnPanelStateChangeListenr mOnPanelStateChangeListenr;
	private Context mContext;
	private int MAX_MIDTH = 0;
	private static final int SPEED = 20;
	private boolean isOperator = false;
	private int direct = 0;
	
	public Panel(Context context, int width, int height) {
		super(context);
		mContext = context;
		LayoutParams lp = new LayoutParams(width, height);
		if (direct == 1) {
			lp.rightMargin = -lp.width;
			MAX_MIDTH = Math.abs(lp.rightMargin);
		} else {
			lp.leftMargin = -lp.width;
			MAX_MIDTH = Math.abs(lp.leftMargin);
		}
		
		this.setLayoutParams(lp);
	}
	
	
	public Panel(Context context, View bindView, View contentView, View viewBeside, int width, int height, int direct) {
		this(context,width,height);
		direct = direct;
		
	    //必须改变Panel左侧组件的weight属性   
        LayoutParams p=(LayoutParams) viewBeside.getLayoutParams();   
        p.weight=1;//支持挤压   
        viewBeside.setLayoutParams(p); 
		
		setBindView(bindView);
		
		setContentView(contentView);
	}
	
	public void setBindView(View bindView) {
		bindView.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				LayoutParams lp = (LayoutParams)getLayoutParams();
				Log.e(TAG, "bindView onclick leftMargin = "+lp.leftMargin);
				if (isOperator == true) {
					return;
				}else {
					isOperator = true;
				}
				if (lp.rightMargin < 0 || lp.leftMargin < 0) {
					new AsyncMove().execute(new Integer[] { SPEED });// 正数展开  
				} else {
					new AsyncMove().execute(new Integer[] { -SPEED });// 负数展开  
				}
				
			}
			
		});
	}
	
	public void setContentView(View contentView) {
		this.addView(contentView);
	}
	
	public interface OnPanelStateChangeListenr {
		void onPanelOpened(Panel panel);
		void onPanelCloseed(Panel panel);
	}
	
	public void setOnPanelStateChangeListenr(OnPanelStateChangeListenr listener) {
		this.mOnPanelStateChangeListenr = listener;
	}
	
	class AsyncMove extends AsyncTask<Integer, Integer, Void> {

		@Override
		protected Void doInBackground(Integer... params) {
            int times;   
            if (MAX_MIDTH % Math.abs(params[0]) == 0)// 整除   
                times = MAX_MIDTH / Math.abs(params[0]);   
            else  
                times = MAX_MIDTH / Math.abs(params[0]) + 1;// 有余数   
            Log.e(TAG, "doInBackground times = "+times);
            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... values) {
            LayoutParams lp = (LayoutParams)getLayoutParams();   
            if (values[0] < 0){//关闭   
            	if (direct == 1) {
            		lp.rightMargin = Math.max(lp.rightMargin + values[0],-MAX_MIDTH);   
            	} else {
            		lp.leftMargin = Math.max(lp.leftMargin + values[0],-MAX_MIDTH);
            	}
            }   
            else{//打开   
            	if (direct == 1) {
            		lp.rightMargin = Math.min(lp.rightMargin + values[0],MAX_MIDTH);   
            	} else {
            		lp.leftMargin = Math.min(lp.leftMargin + values[0],MAX_MIDTH);	
            	}
            }   
            if (direct == 1) {
            	if(lp.rightMargin==0 && mOnPanelStateChangeListenr!=null){//展开之后   
            		mOnPanelStateChangeListenr.onPanelOpened(Panel.this);//调用OPEN回调函数   
            	}   
            	else if(lp.rightMargin==-MAX_MIDTH && mOnPanelStateChangeListenr!=null){//收缩之后   
            		mOnPanelStateChangeListenr.onPanelCloseed(Panel.this);//调用CLOSE回调函数   
            	}   
            } else {
            	if(lp.leftMargin==0 && mOnPanelStateChangeListenr!=null){//展开之后   
            		mOnPanelStateChangeListenr.onPanelOpened(Panel.this);//调用OPEN回调函数   
            	}   
            	else if(lp.leftMargin==-MAX_MIDTH && mOnPanelStateChangeListenr!=null){//收缩之后   
            		mOnPanelStateChangeListenr.onPanelCloseed(Panel.this);//调用CLOSE回调函数   
            	}              	
            }
            
            if (lp.rightMargin==0 || lp.rightMargin==-MAX_MIDTH || lp.leftMargin==0 || lp.leftMargin==-MAX_MIDTH) {
            	isOperator = false;
            }
            
            Log.e(TAG, "onProgressUpdate");
            setLayoutParams(lp);   
		}
		
		
	}
}

package com.android.PanelDemo;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.android.PanelDemo.Panel.OnPanelStateChangeListenr;


public class PanelViewDemoActivity extends Activity {
    private static final String TAG = "PanelViewDemoActivity";
	private Panel mPanel;
	private LinearLayout mLinearLayout;
	private Button mPanelButton;
	private TextView mTextView;
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        mLinearLayout = (LinearLayout)findViewById(R.id.mLinearlayout_id);
        mPanelButton = (Button)findViewById(R.id.mButton_id);
        mTextView = (TextView)findViewById(R.id.mTextView_id);
        
        LayoutInflater mInflater = LayoutInflater.from(this);
        View contentView = mInflater.inflate(R.layout.mypanel, null);
        
        mPanel = new Panel(this, mPanelButton, contentView, mTextView, 100, LayoutParams.FILL_PARENT, 0);
        mPanel.setOnPanelStateChangeListenr(new OnPanelStateChangeListenr() {

			@Override
			public void onPanelCloseed(Panel panel) {
				// TODO Auto-generated method stub
				//Toast.makeText(PanelViewDemoActivity.this, "panel Close!!", Toast.LENGTH_SHORT).show();
				Log.e(TAG, "onPanelCloseed");
			}

			@Override
			public void onPanelOpened(Panel panel) {
				// TODO Auto-generated method stub
				//Toast.makeText(PanelViewDemoActivity.this, "panel open!!", Toast.LENGTH_SHORT).show();
				Log.e(TAG, "onPanelOpened");
			}
        	
        });
        mLinearLayout.addView(mPanel,0);
    }
    
    
}

<?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/mLinearlayout_id" android:layout_width="fill_parent" android:layout_height="fill_parent"
	    android:layout_weight="1"  android:orientation="horizontal"
	    >
	    <TextView 
	        android:id="@+id/mTextView_id" android:layout_width="fill_parent" android:layout_height="fill_parent"
	        android:text="Panel 测试"
	        />
	</LinearLayout>
	
	<LinearLayout 
	    android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="#ffffffff"
	    >
	    <Button 
	        android:id="@+id/mButton_id" android:layout_width="wrap_content" android:layout_height="wrap_content"
	        android:text="Panel" android:layout_gravity="left"
	        />
	</LinearLayout>
</LinearLayout>

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <Button 
        android:id="@+id/mPanelButton1_id" android:layout_width="wrap_content" android:layout_height="wrap_content"
        android:text="测试1"
        />

    <Button 
        android:id="@+id/mPanelButton2_id" android:layout_width="wrap_content" android:layout_height="wrap_content"
        android:text="测试2"
        />
    
    <Button 
        android:id="@+id/mPanelButton3_id" android:layout_width="wrap_content" android:layout_height="wrap_content"
        android:text="测试3"
        />
</LinearLayout>
这是一种实现方法,当然我也可以用动画来实现,下面我们来实现一下:(有时间编辑)

SwipePanel(侧划控件)Background对市面上实现的侧划返回不是很满意(仿微信,QQ 通过修改窗口透明坑太多),最终决定还是亲手写一个高实用性的吧,效果如下所示,换个图标,更多划动功能可以由你自己解锁,总共一个 600 多行代码的类,推荐通过阅读源码,你肯定会收获很多哈。Preview DownloadGradle:implementation 'com.blankj:swipe-panel:1.0'How to use动态final SwipePanel swipePanel = new SwipePanel(this); swipePanel.setLeftEdgeSize(SizeUtils.dp2px(100));// 设置左侧触发阈值 100dp swipePanel.setLeftDrawable(R.drawable.base_back);// 设置左侧 icon swipePanel.wrapView(findViewById(R.id.rootLayout));// 设置嵌套在 rootLayout 外层 swipePanel.setOnFullSwipeListener(new SwipePanel.OnFullSwipeListener() {// 设置完全划开松手后的监听     @Override     public void onFullSwipe(int direction) {         finish();         swipePanel.close(direction);// 关闭     } });静态<com.blankj.swipepanel.SwipePanel         xmlns:android="http://schemas.android.com/apk/res/android"         xmlns:tools="http://schemas.android.com/tools"         xmlns:app="http://schemas.android.com/apk/res-auto"         android:id="@ id/swipePanel"         android:background="@color/mediumGray"         android:layout_width="match_parent"         android:layout_height="match_parent"         tools:context=".LayoutSwipePanelActivity"         app:isLeftCenter="false"         app:leftEdgeSize="100dp"         app:leftSwipeColor="@color/colorPrimary"         app:leftDrawable="@drawable/base_back">     ... </com.blankj.swipepanel.SwipePanel>API方法名属性名说明setLeft(Top, Right, Bottom)SwipeColorapp:left(top, right, bottom)SwipeColor设置左(上、右、下)测颜色setLeft(Top, Right, Bottom)EdgeSizeapp:left(top, right, bottom)EdgeSize设置左(上、右、下)测触发阈值setLeft(Top, Right, Bottom)Drawableapp:left(top, right, bottom)Drawable设置左(上、右、下)测 iconsetLeft(Top, Right, Bottom)Centerapp:isLeft(Top, Right, Bottom)Center设置左(上、右、下)测是否居中setLeft(Top, Right, Bottom)Enabledapp:isLeft(Top, Right, Bottom)Enabled设置左(上、右、下)测是否可用wrapView---设置嵌套在该 view 的外层setOnFullSwipeListener---设置完全划开松手后的监听isOpen---判断是否被划开close---关闭
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值