欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android實(shí)現(xiàn)Z軸布局效果

 更新時(shí)間:2020年08月26日 14:28:29   作者:楊天睿  
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)Z軸布局效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

如果需要在布局中創(chuàng)造一個(gè)層疊的概念,那么使用Android系統(tǒng)中的ViewGroup是不夠的,但是可以通過改變ViewGroup的繪制順序?qū)崿F(xiàn)

代碼下載

繼承自FrameLayout

FrameLayout已經(jīng)幫我們實(shí)現(xiàn)了子View的measure和layout過程,我們只需在它的基礎(chǔ)上改變繪制順序即可

自定義LayoutParams

layoutParams的作用是向父布局請(qǐng)求布局參數(shù)(MeasureSpec),這個(gè)參數(shù)會(huì)在View inflate時(shí)添加到布局中,我們?nèi)绻褂肔ayoutParams將會(huì)得到很大的方便

// 這里繼承FrameLayout的LayoutParams即可
public static class LayoutParams extends FrameLayout.LayoutParams {

 public final static int DEFAULT_ZORDER = 1;

 public int zOrder;

 public LayoutParams(@NonNull Context c, @Nullable AttributeSet attrs) {
  super(c, attrs);
  TypedArray a = c.obtainStyledAttributes(attrs, R.styleable.ZOrderLayout);
  zOrder = a.getInt(R.styleable.ZOrderLayout_layout_zorder, DEFAULT_ZORDER);
  a.recycle();
 }
}

我們自定義個(gè)Attribute,那么就可以在XML中進(jìn)行使用了

<declare-styleable name="ZOrderLayout">
 <attr name="layout_zorder" format="integer"/>
</declare-styleable>

這樣我們的View就可以這么使用

<!--layout_zorder 表示該View在第1層-->
<tianrui.viewgroup.MyTextView
 android:text="0"
 android:layout_width="50dp"
 android:layout_height="50dp"
 android:background="@android:color/holo_red_light"
 app:layout_zorder="1"/>

<!--layout_zorder=2 表示該View在第2層-->
<tianrui.viewgroup.MyTextView
 android:text="1"
 android:layout_width="50dp"
 android:layout_height="50dp"
 android:layout_marginLeft="20dp"
 android:background="@android:color/holo_blue_light"
 app:layout_zorder="2"/>

同時(shí)需要重寫ViewGroup的generateLayoutParams(),讓它生成我們的LayoutParams

初始化繪制順序

在所有的子View加載完成后初始化需要繪制的順序(根據(jù)我們的ZorderLayoutParams)

@Override
protected void onFinishInflate() {
 super.onFinishInflate();
 initialZOrder();
}


private void initialZOrder() {
 final int childCount = getChildCount();
 View view;
 ZOrderLayout.LayoutParams params;
 for (int i = 0; i < childCount; i++) {
  view = getChildAt(i);
  params = (LayoutParams) view.getLayoutParams();

  Pair<View, Integer> pair = new Pair<>(view, params.zOrder);
  list.add(pair);
 }

 // 根據(jù)Zorder屬性,進(jìn)行排序
 Collections.sort(list, new Comparator<Pair<View, Integer>>() {
  @Override
  public int compare(Pair<View, Integer> o1, Pair<View, Integer> o2) {
   return o1.second - o2.second;
  }
 });
}

獲取所有的子View,然后根據(jù)他們的ZOrder進(jìn)行排序,onFinishInflate()會(huì)在裝載完所有的子View后進(jìn)行回調(diào)

改變View的繪制順序

這里使用排好序的View繪制順序就可以了, 記得調(diào)用setChildrenDrawingOrderEnabled(true);

@Override
protected int getChildDrawingOrder(int childCount, int i) {
 return indexOfChild(list.get(i).first);
}

Demo演示

<?xml version="1.0" encoding="utf-8"?>
<tianrui.viewgroup.view.ZOrderLayout
 xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:app="http://schemas.android.com/apk/res-auto"
 android:layout_width="match_parent"
 android:layout_height="match_parent">


 <tianrui.viewgroup.MyTextView
  android:text="0"
  android:layout_width="50dp"
  android:layout_height="50dp"
  android:background="@android:color/holo_red_light"
  app:layout_zorder="1"/>


 <tianrui.viewgroup.MyTextView
  android:text="1"
  android:layout_width="50dp"
  android:layout_height="50dp"
  android:layout_marginLeft="20dp"
  android:background="@android:color/holo_blue_light"
  app:layout_zorder="2"/>


 <tianrui.viewgroup.MyTextView
  android:text="2"
  android:layout_width="50dp"
  android:layout_height="50dp"
  android:layout_marginLeft="40dp"
  android:background="@android:color/holo_orange_light"
  app:layout_zorder="3"/>


 <tianrui.viewgroup.MyTextView
  android:text="3"
  android:layout_width="50dp"
  android:layout_height="50dp"
  android:layout_marginLeft="60dp"
  android:background="@android:color/holo_green_light"
  app:layout_zorder="2"/>


 <tianrui.viewgroup.MyTextView
  android:text="4"
  android:layout_width="50dp"
  android:layout_height="50dp"
  android:layout_marginLeft="80dp"
  android:background="@android:color/holo_purple"
  app:layout_zorder="1"/>

</tianrui.viewgroup.view.ZOrderLayout>

可以看出這個(gè)布局是中間的zorder最高,表示中間的會(huì)壓在兩邊的上邊,而最左(右)的繪制層級(jí)(zorder)為1, 表示會(huì)繪制在最下面

完整代碼

public class ZOrderLayout extends FrameLayout {


 private List<Pair<View, Integer>> list = new ArrayList<>();


 public ZOrderLayout(@NonNull Context context) {
  this(context, null);
 }

 public ZOrderLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
  this(context, attrs, 0);
 }

 public ZOrderLayout(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) {
  super(context, attrs, defStyleAttr);
  setChildrenDrawingOrderEnabled(true);
 }


 @Override
 protected int getChildDrawingOrder(int childCount, int i) {
  return indexOfChild(list.get(i).first);
 }


 @Override
 protected void onFinishInflate() {
  super.onFinishInflate();
  initialZOrder();
 }


 private void initialZOrder() {
  final int childCount = getChildCount();
  View view;
  ZOrderLayout.LayoutParams params;
  for (int i = 0; i < childCount; i++) {
   view = getChildAt(i);
   params = (LayoutParams) view.getLayoutParams();

   Pair<View, Integer> pair = new Pair<>(view, params.zOrder);
   list.add(pair);
  }

  Collections.sort(list, new Comparator<Pair<View, Integer>>() {
   @Override
   public int compare(Pair<View, Integer> o1, Pair<View, Integer> o2) {
    return o1.second - o2.second;
   }
  });
 }

 /**
  * 在解析xml時(shí),會(huì)解析每個(gè)跟布局的LayoutParams
  */
 @Override
 public LayoutParams generateLayoutParams(AttributeSet attrs) {
  return new LayoutParams(getContext(), attrs);
 }

 public static class LayoutParams extends FrameLayout.LayoutParams {

  public final static int DEFAULT_ZORDER = 1;

  public int zOrder;

  public LayoutParams(@NonNull Context c, @Nullable AttributeSet attrs) {
   super(c, attrs);
   TypedArray a = c.obtainStyledAttributes(attrs, R.styleable.ZOrderLayout);
   zOrder = a.getInt(R.styleable.ZOrderLayout_layout_zorder, DEFAULT_ZORDER);
   a.recycle();
  }
 }
}

以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Android高德地圖marker自定義彈框窗口

    Android高德地圖marker自定義彈框窗口

    這篇文章主要為大家詳細(xì)介紹了Android高德地圖marker自定義彈框窗口,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-04-04
  • 使用Eclipse配置android開發(fā)環(huán)境教程

    使用Eclipse配置android開發(fā)環(huán)境教程

    這篇文章主要介紹了使用Eclipse配置android開發(fā)環(huán)境教程,本文講解了下載需要用到的工具、下載完需要的工具之后開始安裝、讓Ecplise自動(dòng)安裝Android開發(fā)插件(ADT- plugin)、配置Andiord SDK路徑、測試開發(fā)一個(gè)Android項(xiàng)目等內(nèi)容,需要的朋友可以參考下
    2015-04-04
  • Android json數(shù)據(jù)解析詳解及實(shí)例代碼

    Android json數(shù)據(jù)解析詳解及實(shí)例代碼

    這篇文章主要介紹了 Android json數(shù)據(jù)解析詳解及實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下
    2017-02-02
  • Android開發(fā) -- 控件的顯示與隱藏 setVisibility View.VISIBLE View.INVISIBLE View.GONE

    Android開發(fā) -- 控件的顯示與隱藏 setVisibility View.VISIBLE View.INVISI

    本文簡單介紹在Android開發(fā)中控件的顯示與隱藏幾種常見的屬性,給大家一個(gè)參考,希望對(duì)大家學(xué)習(xí)有所幫助。
    2016-06-06
  • Android SurfaceView基礎(chǔ)用法詳解

    Android SurfaceView基礎(chǔ)用法詳解

    這篇文章主要介紹了Android SurfaceView基礎(chǔ)用法詳解,本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • Android實(shí)現(xiàn)EditText內(nèi)容保存為Bitmap的方法

    Android實(shí)現(xiàn)EditText內(nèi)容保存為Bitmap的方法

    這篇文章主要介紹了Android實(shí)現(xiàn)EditText內(nèi)容保存為Bitmap的方法,涉及Android中saveBitmap方法的簡單使用技巧,需要的朋友可以參考下
    2016-01-01
  • Android編程中軟鍵盤基本用法分析

    Android編程中軟鍵盤基本用法分析

    這篇文章主要介紹了Android編程中軟鍵盤基本用法,結(jié)合實(shí)例形式分析了Android軟鍵盤的顯示、隱藏與使用注意事項(xiàng),需要的朋友可以參考下
    2016-10-10
  • android實(shí)現(xiàn)ViewPager懶加載的三種方法

    android實(shí)現(xiàn)ViewPager懶加載的三種方法

    這篇文章主要介紹了android實(shí)現(xiàn)ViewPager懶加載的三種方法,懶加載在項(xiàng)目運(yùn)用中很廣泛,可以提高運(yùn)行速度,有興趣的可以了解一下。
    2017-03-03
  • Android開發(fā)簡易音樂播放器

    Android開發(fā)簡易音樂播放器

    這篇文章主要為大家詳細(xì)介紹了Android開發(fā)簡易音樂播放器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-12-12
  • 詳解Android 傳感器開發(fā) 完全解析

    詳解Android 傳感器開發(fā) 完全解析

    對(duì)于傳感器的使用,不同版本的Android手機(jī)也許存在較大的硬件差異,本篇文章主要介紹了Android 傳感器開發(fā),有興趣的可以了解一下。
    2016-12-12

最新評(píng)論