編輯:關於Android編程
有些時候,自己要在布局文件中重復書寫大量的代碼來定義一個布局。這是最基本的使用,當然要掌握;但是有些場景都去對應的布局裡面寫對應的屬性,就顯得很無力。會發現,系統自帶的控件無法滿足我們的要求,這個時候就要考慮自定義控件。自定義view的世界,也很浩瀚,個人需要學的地方還有很多很多。自定義view,會節省開發效率,很有必要學習其基本原理和方法。接下來就對自定義view,做一個初步的認識,一步步了解封裝的重要性。但是,也僅僅是一個初步,因為它實在太靈活了。
有這麼一種場景,看圖:
除了布局之外,還有一點。當用戶點擊的時候,會自動選中復選框,而且紅色textview變為綠色。且改變了內容。
那就一點點的看看怎麼通過自定義view和自定義屬性來完成上述功能。
首先,它是顯示在一個活動中的。這個活動,就定位為SettingCenterActivity,要在這個活動中加載上面的的布局。通過以前的方式來完成一下布局上的功能。就使用線性布局,冗余的代碼寫了出來:
定義一個activity_settingcenter.xml:
運行程序,已經實現了效果。但是,如果繼續顯示“黑名單攔截設置”設置更多的話,或者要修改每一項的參數屬性值的話,就要不斷的重復寫代碼了,這樣顯然浪費時間。
所以,做第一步封裝:
把這個布局抽取成一個布局,item_settingcenterview.xml
activity_settingcenter.xml中像類似引用textview一樣就好了!其實,textview在代碼中是一個類,繼承自view才有了view的功能。那麼我們就自己定義一個類,繼承自某個容器類型的view,會不會有view的屬性和功能了?答案是肯定的,因為子類使用父類功能,天經地義,子類都比父類要強大!能像使用LinearLayout一樣使用自定義的view
繼續改進(自定義view解決上面的一切問題)。
新建一個類SettingCenterItenView繼承自LinearLayout類,加入如下功能:
package com.example.ydlmobileguard.views; import android.content.Context; import android.util.AttributeSet; import android.widget.LinearLayout; public class SettingCenterItemView extends LinearLayout { public SettingCenterItemView(Context context, AttributeSet attrs) { super(context, attrs); initView(); } public SettingCenterItemView(Context context) { super(context); initView(); } private void initView() { // TODO Auto-generated method stub } }繼承自LinearLayout,因為LinearLayout屬於容器類型的view,他可以填充其他的view。你也可以繼承自RelativeLayout都可以
package com.example.ydlmobileguard.views; import com.example.ydlmobileguard.R; import android.content.Context; import android.util.AttributeSet; import android.view.View; import android.widget.LinearLayout; public class SettingCenterItemView extends LinearLayout { public SettingCenterItemView(Context context, AttributeSet attrs) { super(context, attrs); initView(); } public SettingCenterItemView(Context context) { super(context); initView(); } private void initView() { View view = View.inflate(getContext(), R.layout.item_settingcenter_view, null); addView(view); } }
還沒結束。如果就這麼結束了,就成了蒙你了。。。因為還是無法修改每一項的內容,場景還沒解決。接下來,還要自定義屬性對文字做一個動態修改。
在自定義屬性前,先看一下系統的屬性是怎麼來設置的。
都會發現每一個配置文件中有一行命名空間:xmlns:android="http://schemas.android.com/apk/res/android" 這是系統自帶的,它的原理是:通過命名空間的前綴,找到包的信息(這裡是最後一個名稱android),通過包的信息,找到工程,找到工程後。就可以找到這個工程的資源信息(values----attrs屬性配置文件),從attrs文件裡找到屬性配置的信息。先在activity_settingcenter.xml裡面加入自己供自定義view使用的命名空間前綴 如下:xmlns:itydl="http://schemas.android.com/apk/res/com.example.ydlmobileguard"
再參考一下系統的attrs文件怎麼寫的——
在這裡面,起著最主要作用的是一個是屬性名稱,在布局文件中可以直引用,一個是屬性值得類型。
比對之,定義自己的屬性文件
新建attrs.xml文件,加入針對自定義view要添加的屬性名和屬性值
在SettingCenterItemView類中完成代碼如下:
package com.example.ydlmobileguard.views; import com.example.ydlmobileguard.R; import android.content.Context; import android.util.AttributeSet; import android.view.View; import android.widget.CheckBox; import android.widget.LinearLayout; import android.widget.TextView; public class SettingCenterItemView extends LinearLayout { private TextView tv_title; private TextView tv_content; private CheckBox cb_checkBox; /** * 代碼實例化,調用構造函數。引用這個自定義view,就會自動調用這裡的構造函數 * @param context * @param attrs */ public SettingCenterItemView(Context context, AttributeSet attrs) { super(context, attrs); initView(); /** * namespace :The namespace of the attribute to get the value from. name :The name of the attribute to get the value from. */ //根據命名空間/屬性文件中的屬性值。在自定義組件xml文件中得到值 String title =attrs.getAttributeValue("http://schemas.android.com/apk/res/com.example.ydlmobileguard", "title"); String content = attrs.getAttributeValue("http://schemas.android.com/apk/res/com.example.ydlmobileguard", "content"); //把獲取到的值,加載到view上顯示 tv_title.setText(title); tv_content.setText(content); } public SettingCenterItemView(Context context) { super(context); initView(); } /** * 初始化LinearLayout子組件 */ private void initView() { //給LinearLayout加上子組件 View view = View.inflate(getContext(), R.layout.item_settingcenter_view, null); //每一項的標題 tv_title = (TextView) view.findViewById(R.id.tv_settingcenter_autoupdate_title); //每一項內容 tv_content = (TextView) view.findViewById(R.id.tv_settingcenter_autoupdate_content); //每一項的復選框 cb_checkBox = (CheckBox) view.findViewById(R.id.cb_settingcenter_autoupdate_checked); addView(view);//Adds a child view. } }
這個時候自定義view算是介紹完了。
最後完成“”特效“,添加背景顏色,添加選擇器,點擊每一項,chackbox也跟著選中或者取消選中。完整代碼在線面給出:
package com.example.ydlmobileguard.views; import android.content.Context; import android.graphics.Color; import android.util.AttributeSet; import android.view.View; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.LinearLayout; import android.widget.TextView; import com.example.ydlmobileguard.R; public class SettingCenterItemView extends LinearLayout { private TextView tv_title; private TextView tv_content; private CheckBox cb_checkBox; private String[] contents; private View item; /** * 代碼實例化,調用構造函數。引用這個自定義view,就會自動調用這裡的構造函數 * @param context * @param attrs */ public SettingCenterItemView(Context context, AttributeSet attrs) { super(context, attrs); initView();//初始化組件界面 initEvent();//初始化組件事件 /** * namespace :The namespace of the attribute to get the value from. name :The name of the attribute to get the value from. */ //根據命名空間/屬性文件中的屬性值。在自定義組件xml文件中得到值 String title =attrs.getAttributeValue("http://schemas.android.com/apk/res/com.example.ydlmobileguard", "title"); String content = attrs.getAttributeValue("http://schemas.android.com/apk/res/com.example.ydlmobileguard", "content"); //把獲取到的值,加載到view上顯示 tv_title.setText(title); //利用正則表達式,截取content內容。自動更新已經關閉-自動更新已經開啟。其中,contents[0]=自動更新已經關閉;contents[1]=自動更新已經開啟 contents = content.split("-"); } /** * chu shi hua fu xuan kuang zu jian */ private void initEvent() { //item item.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { cb_checkBox.setChecked(!cb_checkBox.isChecked()); } }); cb_checkBox.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if(isChecked){//clicked tv_content.setTextColor(Color.GREEN); tv_content.setText(contents[1]); }else{//unclicked tv_content.setTextColor(Color.RED); tv_content.setText(contents[0]); } } }); } public SettingCenterItemView(Context context) { super(context); initView(); } /** * 初始化LinearLayout子組件 */ private void initView() { //給LinearLayout加上子組件。這個item指的就是item_settingcenter_view文件裡的RelativeLayout item = View.inflate(getContext(), R.layout.item_settingcenter_view, null); //每一項的標題 tv_title = (TextView) item.findViewById(R.id.tv_settingcenter_autoupdate_title); //每一項內容 tv_content = (TextView) item.findViewById(R.id.tv_settingcenter_autoupdate_content); //每一項的復選框 cb_checkBox = (CheckBox) item.findViewById(R.id.cb_settingcenter_autoupdate_checked); addView(item);//Adds a child view. } }
最後再總結一下自定義屬性:
1,自定義命名空間
xmlns:itheima="http://schemas.android.com/apk/res/工程的包名"
2,創建attrs.xml文件
3,在自定義組件中使用自定義屬性
public SettingCenterItemView(Context context, AttributeSet attrs) {
super(context, attrs);
initView();
initEvent();
String content = attrs.getAttributeValue("http://schemas.android.com/apk/res/工程包名", "自定義屬性名");
String title = attrs.getAttributeValue("http://schemas.android.com/apk/res/com.itydl.mobileguard", "title");
tv_title.setText(title);
contents = content.split("-");
}
這僅僅是一個簡單的demo,還有更復雜的自定義view也會在以後繼續討論。
1. 訪問私有數據庫創建一個項目,在項目中利用SQLiteOpenHelper創建一個名稱為account的數據庫,並在數據庫中創建一張名為info的表。public c
我們在一些項目中會用到自定義流式布局,我個人覺得流式布局將呆板的布局錯綜排列,來提升用戶體驗度.(還可以不辜負美工妹子們的期望,人家畢竟也辛辛苦苦設計半天)。今天終於有時
概述:如果你目前還是一名學生或是沒有在應用商店中上傳過應用,恐怕對此的感受不深。而在企業中對Java代碼的混淆卻是一步很重要的步驟,從安全的角度來說,代碼混淆,防止居心不
本文為大家解析Android中如何獲取手機屏幕大小,提供一個解決方法,分享給大家供大家參考,具體內容如下運行效果圖:運行程序後,當我們點擊Button按鈕時,可以看到下面