日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android项目开发实战—自定义左右菜单

發布時間:2024/4/14 Android 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android项目开发实战—自定义左右菜单 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Android實現自定義左右菜單

功能描述:
在左中右三個區域分別承載三個不同的view,把它全部添加進來,而我們實現左右菜單,就是來控制當前顯示的是哪一部分;如果顯示中間菜單,就把中間菜單呈現在用戶面前;如果顯示左菜單,就把左菜單和一部分的中間菜單呈現在用戶面前;如果顯示右菜單,就把右菜單和一部分的中間菜單呈現在用戶面前。即整張圖的左中右不斷移動。

功能實現(step by step):
1、菜單布局(通過擴展,完成基本布局。包含左右菜單布局和中間內容區域,并設置顏色用于區分)2、菜單左右滑動(使用邏輯,找出滑動中間點,并對事件作處理,主要針對滑動事件)3、加入左右滑動動畫(使用Scroll進行滑動事件處理,主要是自動滑動,增加用戶體驗)4、處理點擊事件(通過對左右事件的處理,會阻止點擊事件的處理,這里需要調用系統,返還點擊事件)5、添加蒙板效果(通過增加view,對view的透明度進行處理,從而實現蒙版效果)

核心內容:
1.布局的添加
2.事件分發機制
3.滾動添加
4.蒙版添加

構想圖:

開發過程中遇到的錯誤:
Caused by:java.lang.IllegalStateException:The specified child already has a parent.You must call removeView() on the child’s parent first.
造成這個原因,是組件在父類中重復加載了相同的組件
如:
addView(leftMenu, mLayout); // 第一次添加
addView((leftMenu, , mLayout); // 第二次添加

源代碼:

activity_main.xml:

<RelativeLayout 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"tools:context= ".MainActivity" ></RelativeLayout>

left.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:orientation= "vertical" ><Button android:id="@+id/button1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Button" /></LinearLayout>

MainActivity.java

package com.example.mymenu;import android.os.Bundle; import android.app.Activity; import android.support.v4.app.FragmentActivity; import android.view.Menu;public class MainActivity extends FragmentActivity {private MainUI mainUI ;private LeftMenu leftMenu ;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);//實例化MainUImainUI= new MainUI(this );setContentView( mainUI);//實例化LeftMenuleftMenu= new LeftMenu();getSupportFragmentManager().beginTransaction().add(MainUI. LEFT_ID,leftMenu ).commit();}}

MainUI.java

package com.example.mymenu;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Point;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.animation.DecelerateInterpolator;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;
import android.widget.Scroller;

@SuppressLint(“NewApi” )
public class MainUI extends RelativeLayout{

private Context context ;private FrameLayout leftMenu ;private FrameLayout middleMenu ;private FrameLayout rightMenu ;//設置蒙版private FrameLayout middleMask ;private Scroller mScroller ;//定義左中右菜單的IDpublic static final int LEFT_ID=0xaabbcc;public static final int MIDDLE_ID=0xaaccbb;public static final int RIGHT_ID=0xccbbaa;//繼承自RelativeLayout,并實現兩個構造方法public MainUI(Context context) {super(context);initView(context);}public MainUI(Context context, AttributeSet attrs) {super(context, attrs);initView(context);}public void initView(Context context){this.context =context;mScroller=new Scroller(context, new DecelerateInterpolator()); //渲染器//實例化三個區域leftMenu= new FrameLayout(context);middleMenu=new FrameLayout(context);rightMenu=new FrameLayout(context);middleMask=new FrameLayout(context);//分別為三個區域添加不同的顏色leftMenu.setBackgroundColor(Color. RED);middleMenu.setBackgroundColor(Color.GREEN);rightMenu.setBackgroundColor(Color.RED);middleMask.setBackgroundColor(0x88000000);//蒙版的初始顏色為淺灰色//為自定義的左中右菜單添加IDleftMenu.setId( LEFT_ID);middleMenu.setId(MIDDLE_ID );rightMenu.setId(RIGHT_ID ); //把三個區域全部填充到一個view中,實際上這個view就是我們承載三個區域的最外層的RelativeLayout,也是當前的主文件addView( leftMenu);addView( middleMenu);addView( rightMenu);addView( middleMask);middleMask.setAlpha(0);//設置蒙版的科技度(完全可見),只有在滑動的時候才是不可見的}public float onMiddleMask(){System. out.println("透明度:" +middleMask .getAlpha());return middleMask .getAlpha(); }//根據滑動的距離的變化來設置可見度值的變化@Overridepublic void scrollTo(int x, int y) {super.scrollTo(x, y);onMiddleMask();int curX=Math.abs(getScrollX());float scale=curX/(float)leftMenu.getMeasuredWidth(); //計算整個可見寬度middleMask.setAlpha(scale);}//在把三個區域添加到Layout之前,先對它們的寬和高進行測量@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {//widthMeasureSpec,heightMeasureSpec是當前屏幕的寬度和高度super.onMeasure(widthMeasureSpec, heightMeasureSpec);//中間菜單的寬和高即為當前屏幕的寬和高middleMenu.measure(widthMeasureSpec, heightMeasureSpec);//獲取蒙版的寬和高middleMask.measure(widthMeasureSpec, heightMeasureSpec);//得到當前屏幕的真實寬度int realWidth=MeasureSpec.getSize(widthMeasureSpec);//計算所需要的寬度int tempWidthMeasure=MeasureSpec.makeMeasureSpec(( int)(realWidth*0.8f),MeasureSpec.EXACTLY);//為左右菜單設置相應的寬度leftMenu.measure(tempWidthMeasure, heightMeasureSpec);rightMenu.measure(tempWidthMeasure, heightMeasureSpec); }//把三個區域添加到Layout中@Overrideprotected void onLayout(boolean changed, int l, int t, int r, int b) {//五個參數(改變監聽,left,top,right,bottom)super.onLayout(changed, l, t, r, b);//設置三個區域在layout中的位置middleMenu.layout(l, t, r, b);middleMask.layout(l, t, r, b);leftMenu.layout(l- leftMenu.getMeasuredWidth(), t, l, b);//(l-leftMenu.getMeasuredWidth(), t, r, b)rightMenu.layout(r,t,r+ rightMenu.getMeasuredWidth(),b); //(l+middleMenu.getMeasuredWidth(), t, l+middleMenu.getMeasuredWidth()+rightMenu.getMeasuredWidth(), b)}private boolean isTestCompete ;private boolean isleftrightEvent ;//標識上下滑動和左右滑動,左右滑動為true,上下滑動為false//事件分發@Overridepublic boolean dispatchTouchEvent(MotionEvent ev) {//檢測到一個事件,判斷是什么事件(上下滑動事件、左右滑動事件、點擊事件)if (!isTestCompete ) {//沒有初始化,默認為falsegetEventType(ev); //創建一個判斷處理事件的方法return true ;}if (isleftrightEvent ) {//左右滑動應該觸發的響應switch (ev.getActionMasked()) {case MotionEvent.ACTION_MOVE://你手指滑動的距離即為當前屏幕滑動的距離int curScrollX=getScrollX();//定義屏幕滑動的距離int dis_x=(int )(ev.getX()-point.x);//定義手指滑動的距離int expectX=-dis_x+curScrollX;//根據差值判斷是向左滑動還是向右滑動(差值大于20是向右滑動;差值小于20是向左滑動)int finalX=0; //定義屏幕最終的左右滑動距離if (expectX<0) {//向左finalX=Math. max(expectX, -leftMenu.getMeasuredWidth());//最大值} else{ //向右finalX=Math. min(expectX, rightMenu.getMeasuredWidth());//最小值}scrollTo(finalX, 0); //使屏幕移動到最終的位置point. x=( int)ev.getX();break;case MotionEvent.ACTION_UP:case MotionEvent.ACTION_CANCEL:curScrollX=getScrollX();if (Math.abs(curScrollX)> leftMenu.getMeasuredWidth() >> 1) {//當屏幕滑動的距離大于左右菜單的一半時,自動跳到相應的菜單if (curScrollX<0) {mScroller.startScroll(curScrollX,0,- leftMenu.getMeasuredWidth()-curScrollX, 0,200); //起始X,起始Y,終止X,終止Y} else {mScroller.startScroll(curScrollX,0,leftMenu.getMeasuredWidth()-curScrollX, 0,200);}} else {//返回原點mScroller.startScroll(curScrollX,0,-curScrollX, 0,200);}invalidate(); //調用view的重繪方法進行刷新isleftrightEvent=false ;isTestCompete=false ; break;}} else{//對上下滑動和點擊觸發的響應switch (ev.getActionMasked()) {case MotionEvent.ACTION_UP:isleftrightEvent=false ;isTestCompete=false ;break;default: break;}}return super .dispatchTouchEvent(ev);}//重寫回調方法,使左右菜單進行滑動@Overridepublic void computeScroll() {super.computeScroll();if (mScroller .computeScrollOffset()) {return;}int tempX=mScroller .getCurrX();scrollTo(tempX, 0);}private Point point =new Point(); //獲取當前屏幕的點,通過點來計算滑動的距離,根據滑動的距離來判斷相應的事件是滑動還是點擊private static final int TEST_DIS=20; //如果移動距離大于20就定義為滑動//判斷處理事件private void getEventType(MotionEvent ev) {switch (ev.getActionMasked()) {case MotionEvent.ACTION_DOWN:point. x=( int) ev.getX();//floatpoint. y=( int) ev.getY();super.dispatchTouchEvent(ev);break;case MotionEvent.ACTION_MOVE:int dX= Math.abs(( int)ev.getX()-point .x );//獲取水平方向上移動距離的絕對值int dY=Math.abs(( int)ev.getY()-point .y );//獲取垂直方向上移動距離的絕對值if (dX>=TEST_DIS && dX>dY) {//左右滑動isleftrightEvent=true ;isTestCompete=true ; //允許進入接下來的返出測試階段//獲取當前點的 xy坐標point. x=( int) ev.getX();//floatpoint. y=( int) ev.getY();} else if (dY>=TEST_DIS && dY>dX) { //上下滑動isleftrightEvent=false ;isTestCompete=true ;//允許進入接下來的返出測試階段point. x=( int) ev.getX();//floatpoint. y=( int) ev.getY();}break;case MotionEvent.ACTION_UP:case MotionEvent.ACTION_CANCEL://觸摸到屏幕的邊緣//對點擊事件進行處理(返還給系統處理)super.dispatchTouchEvent(ev);isleftrightEvent=false ;isTestCompete=false ;break;}}

}

LeftMeau.java:

package com.example.mymenu;import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup;public class LeftMenu extends Fragment{@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {View v=inflater.inflate(R.layout. left, container,false);//引入left.xml布局文件//為button按鈕添加監聽事件v.findViewById(R.id. button1).setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {System. out.println("Hello LMB!!" ); }});return v;} }

總結

以上是生活随笔為你收集整理的Android项目开发实战—自定义左右菜单的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。