Android開發(fā)之UI常用屬性
介紹控件和布局中的一些屬性和片段
屬性篇
1.屬性android:visibility
(所有控件中都具有的屬性,在progressbar中較常用)
可選值有三種:visible、invisible、gone
invisible表示控件不可見,但它仍然占據(jù)著原來的位置和大小
gone表示控件不可見&控件不占用屏幕空間
還可以在代碼中設置控件的可見性:
setVisibility(View.VISIBLE);傳入View.VISIBLE、View.INVISIBLE或View.GONE三種值
- 關于android中調用某個樣式或者屬性時應該用@還是用?的問題,例如:
style="?android:attr/progressBarStyleHorizontal"
2.dp和sp、dip、px、pt之間的換算問題
- dp(密度無關的像素),一種基于屏幕密度的抽象單位,2英寸3英寸的320像素480像素中,屏幕密度為320/2=160dip。即在每英寸160點的顯示器上,1dp=1px。
(密度為160時,1dp=1px;密度為320時,1dp=2px) - sp(與刻度無關的像素,指定文字大小):與dp類似,但是可以根據(jù)用戶的字體大小首選項進行縮放。
- dip 與dp相同
- px 分辨率
- pt(磅),1/72英寸。
一般Android設置長寬多用dip,設置字體多用sp,在屏幕密度為160時,說明每英寸有160個px,即160px=1in。又因為此時有1sp=1dip=1px(在屏幕密度160的特定條件下),所以有160sp=1in,再加上1pt=1/72in,即72pt=1in,所以72pt=160sp,化簡得1pt≈2.22sp(是一道換算題哦(/▽\))
PS:分辨率與密度的概念:分辨率指相對于軟件來說的顯示像素,以px為單位;密度表示每英寸有多少個像素,density=240->用hdpi標簽的資源,density=160->mdpi,density=120->ldpi
3. 點9圖
左和上繪制的線代表拉伸區(qū)域,右和下繪制的線代表內容被放置區(qū)域
4.碎片(Fragment)
屬于UI片段
讓程序更加合理地利用大屏幕的空間
像這樣:
Amazing!!!
Fragment的用法
導包問題
創(chuàng)建Fragment類所繼承的包使用support-v4,因為它可以讓碎片在所有Android系統(tǒng)版本中保持功能一致性;
而且不需要將該包的依賴添加到build.gradle,因為build.gradle中添加的appcompat-v7庫會將support-v4庫一起引入進來。Activity布局文件中引入fragment時
需要在xml文件中的<fragment>標簽中添加name屬性用來指定Fragment的類,如下:
-
動態(tài)添加碎片的用法
關鍵步驟:
R.id.right_layout
表示界面中的一塊布局區(qū)域的id,如FrameLayout
布局的id。
具體步驟為:
- 創(chuàng)建待添加的碎片實例
- 獲取FragmentManager,在活動中可直接通過
getSupportFragmentManager()
方法得到 - 開啟一個事務,通過調用
beginTransaction()
方法開啟 - 向容器內添加或替換碎片
- 提交事務,調用
commit()
方法來完成
這里有個大坑:
需要讓每個自定義的Fragment
類繼承自android.support.v4.app.Fragment
類。
切記!! android.support.v4.app.Fragment
與android.app.Fragment
不要混用。
MainActivity類要繼承FragmentActivity
類或者AppCompatActivity
類,不然在第二步的getSupportFragmentManager()
方法找不到,會報Cannot resolve method 'getSupportFragmentManager()'錯誤。
如果使用的是AppCompatActivity
類,則需要將theme改成Theme.AppCompat或其派生類,否則會報以下錯誤:
You need to use a Theme.AppCompat theme (or descendant) with this activity.
- 在碎片中模擬返回棧(按下返回鍵不是直接退出程序,而是返回上一個fragment中)
其中的參數(shù)是用于描述返回棧狀態(tài)的名字
- 碎片和活動之間進行通信
- 在碎片中獲取活動的實例:
MainActivity activity=(MainActivity)getActivity();
- 在活動中獲取碎片的實例:
RightFragment rightFragment=(RightFragment)getFragmentManager().findFragmentById(R.id.right_fragment);
- 碎片和碎片之間互相調用:
先在碎片中調用相關聯(lián)的活動,在用這個活動去調用碎片
-
fragment的生命周期
運行狀態(tài):可見&&關聯(lián)的活動在運行
暫停狀態(tài):活動進入暫停狀態(tài)時
停止狀態(tài):活動進入停止狀態(tài)||通過調用FragmentTransaction
的remove()
、replace()
方法從活動中移除&&事務提交之前用了addToBackStack()
方法
銷毀狀態(tài):活動被銷毀時||通過調用FragmentTransaction
的remove()
、replace()
方法從活動中移除&&事務提交之前沒有用用addToBackStack()
方法
- 其它回調:
onAttach()
---碎片和活動建立關聯(lián)
onCreateView()
---為碎片創(chuàng)建視圖(加載布局)時調用
onActivityCreated()
---與之關聯(lián)的活動已創(chuàng)建完畢時
onDestroyView()
---碎片關聯(lián)的視圖被移除時
onDetach()
--碎片和活動解除關聯(lián)時
上一個糊糊的圖:(????)
- 動態(tài)加載布局的技巧
- 使用限定符
Qualifier:在運行時,根據(jù)屏幕大小判斷是使用單頁模式還是雙頁模式
使用步驟:
- 在layout目錄下的main_activity.xml中只寫一個
<fragment>
,在res目錄下再寫一個layout-large目錄,寫兩個<fragment>
,代表雙頁模式,“l(fā)arge”就是限定符,屏幕被認為是large的設備就會自動加載layout-large文件夾下的布局,而小屏幕的設備還是會加載layout文件夾下的布局。
-
碎片的屏幕適配
判斷單頁和雙頁:
在onActivityCreated()方法中判斷:
getActivity().findViewById(R.id....)!=null
判斷能否找到對應id的View,來設置是單頁模式還是雙頁模式,能找到則說明在xml文件中定義了該View,這時可以刷新對應的fragment中的內容:
RightFragment fragment=(RightFragment)getFragmentManager().findFragmentById(R.id....);
fragment.refresh(String stra,String strb);
如果找不到則可以開啟單獨的Activity來顯示內容:
SecondActivity.actionStart(getActivity(),str1,str2...);
actionStart是SecondActivity中的一個靜態(tài)方法,在該方法中打開另一個Activity的話,需要將MainActivity的Context用參數(shù)的方式傳遞過去,而且還需要為SecondActivity添加flag,使SecondActivity放到另一個獨立的任務棧中,具體關于flag的筆記將寫在《Android開發(fā)藝術探索》筆記中。
fragment相關的代碼點這里
5. android:layout_weight屬性
android:layout_width="0dp"
android:layout_weight="1"
如果多個同級控件一起定義了這兩個屬性,而父布局是android:layout_width="match_parent"或android:layout_width="wrap_content"時,兩個控件在水平方向上平分寬度,原理是系統(tǒng)按照該屬性指定的值(上面的例子是“1”)在水平方向上所有控件的layout_weight值的比例劃分寬度,值越大,劃分寬度越大。
如果是如下情況:
<LinearLayout>
<EditText
...
android:layout_width="0dp"
android:layout_weight="1"
/>
<Button
...
android:layout_width="wrap_content"
/>
</LinearLayout>
表明Button的寬度仍然按照wrap_content來計算,而EditText會占滿屏幕所有的剩余空間。
6. gravity和layout_gravity屬性
android:gravity用于設置View中內容相對于View組件的對齊方式;
android:layout_gravity用于設置View組件相對于Container的對齊方式。
說的再直白點,就是android:gravity只對該組件內的東西有效,android:layout_gravity只對組件自身有效。
android:layout_gravity 只在 LinearLayout 和 FrameLayout 中有效
在LinearLayout中:
android:orientation=vertical (垂直) 時,只有水平方向的left,right,center_horizontal
是生效的。
android:orientation=horizontal (水平) 時,只有垂直方向的top,bottom,center_vertical
是生效的。
在FrameLayout布局中:
任意android:layout_gravity屬性都有效
到這里UI的屬性和片段介紹就記完了,后續(xù)對這部分有所領悟還會繼續(xù)添加內容(^^ゞ