Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android初級教程初談自定義view自定義屬性

Android初級教程初談自定義view自定義屬性

編輯:關於Android編程

有些時候,自己要在布局文件中重復書寫大量的代碼來定義一個布局。這是最基本的使用,當然要掌握;但是有些場景都去對應的布局裡面寫對應的屬性,就顯得很無力。會發現,系統自帶的控件無法滿足我們的要求,這個時候就要考慮自定義控件。自定義view的世界,也很浩瀚,個人需要學的地方還有很多很多。自定義view,會節省開發效率,很有必要學習其基本原理和方法。接下來就對自定義view,做一個初步的認識,一步步了解封裝的重要性。但是,也僅僅是一個初步,因為它實在太靈活了。

有這麼一種場景,看圖:

\

除了布局之外,還有一點。當用戶點擊的時候,會自動選中復選框,而且紅色textview變為綠色。且改變了內容。

那就一點點的看看怎麼通過自定義view和自定義屬性來完成上述功能。

首先,它是顯示在一個活動中的。這個活動,就定位為SettingCenterActivity,要在這個活動中加載上面的的布局。通過以前的方式來完成一下布局上的功能。就使用線性布局,冗余的代碼寫了出來:

定義一個activity_settingcenter.xml:

 




    

    

        

        

        

        
    


運行程序,已經實現了效果。但是,如果繼續顯示“黑名單攔截設置”設置更多的話,或者要修改每一項的參數屬性值的話,就要不斷的重復寫代碼了,這樣顯然浪費時間。

 

所以,做第一步封裝:

把這個布局抽取成一個布局,item_settingcenterview.xml

 




    

    

    

    


然後把第一個布局文件中的這一部分刪掉,通過引入進來item_settingcenterview.xml

 

 




    

    
    
    


這時發發現問題好像都解決了,一項接著一項,看似很完美。但是問題又來了,怎麼修改每一項的屬性值呢?好像無從下手。會想到,如果能把整個布局看成一個view,在

 

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都可以
但是,這個時候,好像自定義的SettingCenterItemView什麼也不能做。接下來就在initView裡面。加載一個布局文件,把這個布局文件轉化為一個view組件,再把這個組件加載到容器view中(這裡是LinearLayout)。如下:

 

 

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);
	}
	
	
}

這時,基本的自定義view其實是完成了。去布局文件引用,就可以引用它了,但是注意:自定義的view,必須view名稱要寫全名。

 

 




    

    
    

    
    


重新運行程序,會發現和引入布局顯示的效果一樣。自定義view好像是完成了。能像在布局文件中使用LinearLayout一樣使用我們自己的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要添加的屬性名和屬性值

 



    
        
        
        
    

這個時候,就可以在自定義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. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved