安卓滑動隱藏顯示菜單功能實現(還有蒙板校果),只顯示一半view

好吧.我是標題黨.其實我說的顯示一半的不是activity. 而是看上去像只顯示一半activity.css

但真實的是隻是操做其中一個viewhtml

網上有不少這類的代碼. 但怎麼都不及本身寫的本身理解的深入.前端

這文章給你帶來的只是引導做用.但願能夠幫到像我當初同樣疑惑的人java

首先說頁理android

個人想法是這樣的: 兩個幀佈局. 一上一下. 點擊一下按扭. 上面那個往右顯. 讓下面的那個露出一部份來web

全部的關鍵是操做上面那個佈局的Leftmargin. 而後再開線程來一點點改變Leftmargin的值.讓上面佈局滑動起來網絡

很簡單吧..初當可把我想得糾結死了.網上的案例都很複雜app

若是作過web前端的人應很易理解 . 由於在div+css只會大量應用到這個Leftmargin異步

裏面有大量的註釋...不知道能不能看懂.寫得有點亂.當時很困了async

上草圖

現\

activity_main.xml

<FrameLayout 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" >
    
    
    <include layout="@layout/frame_leftmenu"/>
	
	<include layout="@layout/frame_middlecontent"/>
    
</FrameLayout>


底局layout個人叫fram_leftmenu. 上層的個人叫frame_middlecontent

fram_leftmenu.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:visibility="gone"
    android:id="@+id/leftmenu_layout"
    android:background="#0000cc" >
    
</LinearLayout>


frame_middlecontent.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ffffff"
    android:id="@+id/midcontent_layout" >
    
    <LinearLayout 
        android:id="@+id/middlecontent_first"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <ImageView 
            android:id="@+id/leftmenu_btn_img"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/ic_launcher"/>
    </LinearLayout>
    <LinearLayout 
        android:id="@+id/middlecontent_second"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#e0000000"
        android:visibility="gone">
    </LinearLayout>
</FrameLayout>


這裏是Mainactivtiy.java

package com.hai.goleftright;

import android.app.Activity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;

public class MainActivity extends Activity implements OnTouchListener{
	/**左邊菜單*/
	LinearLayout leftLayout;
	/**右邊菜單*/
	//LinearLayout rightLayout;
	/**蒙板--當middleLayout移動後.該蒙板覆蓋middleLayout*/
	LinearLayout middlecontent_second;
	/**中間內容*/
	FrameLayout midLayout;
	/**用於展開左邊菜單的按扭*/
	ImageView imageView;
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        leftLayout = (LinearLayout) findViewById(R.id.leftmenu_layout);
        //rightLayout = (LinearLayout) findViewById(R.id.rightmenu_layout);
        midLayout = (FrameLayout) findViewById(R.id.midcontent_layout);
        
        imageView = (ImageView) findViewById(R.id.leftmenu_btn_img);
        middlecontent_second = (LinearLayout) findViewById(R.id.middlecontent_second);
        imageView.setOnTouchListener(this);
        middlecontent_second.setOnTouchListener(this);
    }
    
	public boolean onTouch(View v, MotionEvent event) {
		MinLayoutAsyncTask asyncTask = null;
		switch (v.getId()) {
		case R.id.leftmenu_btn_img:
			//設置左邊菜單爲顯狀態
			leftLayout.setVisibility(View.VISIBLE);
			//設置蒙版爲顯示狀態
			middlecontent_second.setVisibility(View.VISIBLE);
			//設置蒙板的透明度
			middlecontent_second.getBackground().setAlpha(50);
			//實例化滑動任務 參數1: 要滑動的layout, 參數2: 最終滑動距離, 參數3: 移動方向
			asyncTask = new MinLayoutAsyncTask(midLayout, 200,"right");
			//開始任務 參數: 每次滑動的距離
			asyncTask.execute(10); 
			break;
		case R.id.middlecontent_second:
			asyncTask = new MinLayoutAsyncTask(leftLayout,midLayout, 0,"left");
			asyncTask.execute(-10);
			middlecontent_second.setVisibility(View.GONE);
			break;
		}
		return true; 
	}
}


線程更新主UI..能夠用 Runnable+ handle的方式, 子線程每更新一次Leftmargin的值就通知主線程更新一下UI. 

只要線程沉睡時間與Leftmargin的值控制得好.即可得動畫滑動效果

我爲告終構方便,書寫簡單. 用的是AsyncTast這個類來實現異步任務

下面這個數就做用就是不停地更新主UI.

MinLayoutAsyncTask.java

package com.hai.goleftright;

import android.os.AsyncTask;
import android.view.View;
import android.widget.FrameLayout;

public class MinLayoutAsyncTask extends AsyncTask<Integer, Integer, Integer> {
	private static final String RIGHT = "right";
	private static final String LEFT = "left";
	/**要顯示的底部rightLayout*/
	View underLayout;
	/**要控制移動的layout*/
	FrameLayout midLayout;
	/**layout的參數對象*/
	FrameLayout.LayoutParams midLayoutParams;
	/**最終距離*/
	int max;
	/**移動方向*/
	String direction;
	/**
	 * 構造器
	 * @param midLayout 要控制的layout
	 * @param speed 每秒的移動距離
	 * @param max 最終要達到的距離
	 * @param 移動方向 "right"/"left"
	 */
	public MinLayoutAsyncTask(View underLayout,View midLayout,int max,String direction){
		this.underLayout = underLayout;
		this.midLayout = (FrameLayout) midLayout;
		this.max = max;
		this.direction = direction;
		
	}
	public MinLayoutAsyncTask(View midLayout,int max,String direction){
		this(null,midLayout,max,direction);
	}
	
	/**
	 * 任務開始前的準備工做
	 */
	@Override
	protected void onPreExecute() {
		midLayoutParams = (FrameLayout.LayoutParams) midLayout.getLayoutParams();
	}
	
	/**
	 * @param speed 該類實例.execute(int i) 傳進來的參數  每次移動的距離
	 */
	@Override
	protected Integer doInBackground(Integer... speed) {
		/**每次進來都先獲取layout的現時leftMargin*/
		int leftMargin = midLayoutParams.leftMargin;
		
		// 根據傳入的速度來滾動界面,當滾動到達最大距離時,跳出循環
		while(true){
			//當前leftMargin加要移動的距離*
			leftMargin = leftMargin + speed[0];
			//移動方向
			if(RIGHT.equals(direction)){
				if(leftMargin > max){
					leftMargin = max;
					break;
				}
			}
			if(LEFT.equals(direction)){
				if(leftMargin < max){
					leftMargin = max;
					break;
				}
			}
			sleep(10);
			publishProgress(leftMargin);
		}
		
		return leftMargin;
	}
	
	@Override
	protected void onProgressUpdate(Integer... leftMargin) {
		midLayoutParams.leftMargin = leftMargin[0];
		midLayout.setLayoutParams(midLayoutParams);
	}
	
	/**
	 * 完成任務後在UI主線程執行的方法 參數是doInBackground返回的結果
	 */
	@Override
	protected void onPostExecute(Integer leftMargin) {
		if(leftMargin == 0){
			underLayout.setVisibility(View.GONE);
		}
		midLayoutParams.leftMargin = leftMargin;
		midLayout.setLayoutParams(midLayoutParams);
	}
	
	private void sleep(int min){
		try {
			Thread.sleep(min);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

}


到這裏就寫完了.

其實代碼有點多.但關鍵理解原理就好了

再一次總結原理

利用幀佈局實面一上一下兩個Layout. 點擊按鈕(或你能夠實現划動事件.我沒寫完)把上層layout往右推過一點

把下層layout顯示出來. 關鍵是控制Leftmargin的值. 而後就是線程更新UI的問題了


其實這裏我以爲還有不少多餘的代碼

由於我爲了實現. "當上層Layout右移以後. 它的全部組件的點擊事件都要失效" 這個想法...

我給上層Layout加上了一層蒙板..這樣上層layout右移以後. 我只要用蒙板去攔截事件就能夠了

這裏應該有更好的辦法.但目前我還沒想到...有好建議的朋友但願補充.


注: 部份優秀代碼來自於網絡,本文總結修改完善

相關文章
相關標籤/搜索