Android 通過Java代碼生成創建界面。動態生成View,動態設置View屬性。addRules詳解


廢話不多說,本文將會層層深入給大家講解如何動態的生成一個完整的界面。

本文內容:

  1. Java代碼中動態生成View
  2. Java代碼中動態設置View的位置,以及其他的屬性
  3. LayoutParams詳解

一、Java代碼中動態的生成View

我們以創建一個Button為例子。 
1、首先我們在onCreate方法中創建一個Button實例:

Button button=new Button(this); 
  • 1

2、創建了Button實例下面我們就要指定它在哪個界面中顯示: 
首先第一步找到我們要顯示的界面: 
首先把setContentView()刪掉(后文會講)。 
有兩種方法:

  • 使用LayoutInflate
  • 使用findViewById

1)LayoutInflate使用來找到一個布局文件:

      ViewGroup viewGroup = (ViewGroup) LayoutInflater.from(this).inflate(R.layout.activity_main, null);
  • 1

返回的是布局文件的最外層的View容器, 
貼一下布局文件中的XML代碼

<?xml version="1.0" encoding="utf-8"?> <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" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.miko.zd.dynamicview.MainActivity" android:id="@+id/relative"> </RelativeLayout> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

這里LayoutInflate返回的就是最外層的RelativeLayout。RelativeLayout繼承於ViewGroup因此完全沒有問題。 
2)通過FindViewByID返回最外層的View 
第二種方法以第一種一致都是返回最外層的RelativeLayout:

        View viewGroup2 = findViewById(R.id.relative);
  • 1

3、下一步就是要把我們的Button添加到RelativeLayout中了 
使用ViewGroup的addView方法:

 viewGroup.addView(button);
  • 1

運行代碼,你會發現界面中什么都沒有,為什么呢? 
前文中說過刪除setContentView()這個方法,setContenView可以理解為,為Activity綁定一個顯示的的布局,我們只是找到了ViewGroup,並且添加了Button,但是沒有綁定Activity,因此這里添加一句setContentView(viewGroup);你可能會說,我一開始不刪除這一句,不可以么? 
findViewById可以,setContentView()一旦調用,layout就會立刻顯示UI,而后的findViewById,找到RelativeLayout實際上已經加載出來了,添加Button,可以理解為顯示出UI后動態的添加View;而inflate只會把Layout形成一個以view類實現成的對象,有需要時再用setContentView(view)顯示出來。 
運行結果: 
這里寫圖片描述 
可以看到,相當原始的界面,下一步我們就要設置Button的位置以及相關屬性了

二、Java代碼中動態設置View的位置,以及其他的屬性

1、首先我們為我們的Button設置一個背景,以及文字:

button.setBackgroundColor(Color.RED); button.setText("Hello World");
  • 1
  • 2

這里寫圖片描述 
2、我們下一步想給Button設置長寬: 
你可能會想button會有setHeight,setWidth方法,確實有,而且你可以實現設置長寬,但是如果你要設置Match_parent,Wrap_content,怎么實現呢?這時候我們就要使用LayoutParam方法了。 
首先創建一個Layoutparams實例:

RelativeLayout.LayoutParams params=new RelativeLayout.LayoutParams(100,100); 
  • 1

不同的布局對應着不同的LayoutParams,我們這里是RelativeLayout所以當然是R.layoutParam這里的兩個參數是Button的寬以及高,注意這里的100代表着100px,使用dp可以參照我之前的博客 
dp轉px

那么上文中的MATCH 以及WRAP怎么實現呢?

RelativeLayout.LayoutParams params=new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
  • 1

運行結果:這里寫圖片描述 
為什么沒有效果呢,因為定義了LayoutParam但是沒有指定哪一個View因此還需要添加一句

        button.setLayoutParams(params);
  • 1

這里寫圖片描述 
沒有任何問題。 
3、設置位置信息 
我們想要使Button居中顯示,怎么實現呢? 
還是使用LayoutParams,使用他的addRules方法:

        params.addRule(RelativeLayout.CENTER_IN_PARENT);
  • 1

這里寫圖片描述 
addRules有兩個方法:

  • addRule(int verb)
  • addRule(int verb, int anchor) 
    verb我們很好理解,就是各種規定位置的參數,anchor代表什么呢? 
    我們看源碼注釋: 
    The id of another view to use as an anchor, 
    * or a boolean value (represented as {@link RelativeLayout#TRUE} 
    * for true or 0 for false). For verbs that don’t refer to another sibling 
    * (for example, ALIGN_WITH_PARENT_BOTTOM) just use -1. 
    實際上verb參數可以分為兩類,一種是不要任何相對view的,比如ALIGN_WITH_PARENT_BOTTOM這種的參數,另一種需要相對view的參數,例如above,right_of等等,需要一個view來表示位置的參數,這個時候就需要用到anchor,anchor代表的是相對view的id。 
    下面我們再創建一個Button:
ViewGroup viewGroup2 = (ViewGroup) viewGroup.findViewById(R.id.relative); Button button = new Button(this); RelativeLayout.LayoutParams params=new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); params.addRule(RelativeLayout.CENTER_IN_PARENT); button.setLayoutParams(params); button.setBackgroundColor(Color.RED); button.setText("Hello World"); button.setId(100); Button button1=new Button(this); RelativeLayout.LayoutParams params1=new RelativeLayout.LayoutParams(200,200); params1.addRule(RelativeLayout.BELOW,100); button1.setLayoutParams(params1); button1.setBackgroundColor(Color.RED); button1.setText("Hello World"); viewGroup2.addView(button); viewGroup2.addView(button1); setContentView(viewGroup);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

注意我們要先給第一個button一個id,因為是動態創建的所以使用setId方法,設id為100, params1.addRule(RelativeLayout.BELOW,100);核心代碼,意思是將button1設置在id為100的view的下方。 
運行結果: 
這里寫圖片描述

四、后記

上文我為大家詳細解析了View的動態創建,以及動態的添加屬性,有幾點需要注意的: 
1、上文中的布局都是用的RelativeLayout,實際上你會發現只有RelativeLayout.layoutParam具有addRules方法,這其實是與XML中相對應的,你在LinearLayout中無法使用Right_of等等相對布局的屬性,這些都是相通的。 實際上我認為在動態生成界面的幾個布局中RelativeLayout是最簡單也是最准確的。 
2、為什么要使用動態生成界面?我想在編程中使用XML是無可厚非的,但是App的大趨勢是動態化來減少版本更替,這就涉及到一個不要寫死的問題,國內已經有很多嘗試,即通過服務器動態生成界面。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM