Android筆記(六十七) 自定義控件

? ? ??實際編程中,系統提供的控件往往無法滿足我們的需求,一來是樣子丑陋,二來是一些復雜的組合需要多次使用的話,每次都寫一堆控件的組合會很耗費時間,所以我們將這些組件的組合自定義為一個新的控件,以后使用的時候直接用該控件,方便又簡單。最常見的例子就是軟件中的titleTar

?

? ? ??實現自定義控件的步驟:

????? 1.設置控件的屬性

????? 2.實現我們的View

????? 3.引用我們自定的View

  官方文檔:http://developer.android.com/training/custom-views/create-view.html

下面開始:

設置控件的屬性:

  分析一下上面四個titleBar,都是由一個居中的文本和一個右邊一個圖片按鈕組成,只不過后面兩個沒有按鈕而已

  那么我們自定義的這個組件就得包含一下幾個基本屬性:文本內容,文本大小,文本顏色,按鈕路徑

  在value中新建一個xml文件attrs.xml,把這些屬性創建出來

<?xml version="1.0" encoding="utf-8"?>
<resources><declare-styleable name="MyCustomTitleBar"><attr name="titleText" format="string"/><attr name="titleTextSize" format="dimension"/><attr name="titleTextColor" format="color"/><attr name="titleButtonImage" format="reference"/></declare-styleable>
</resources>
  declare-styleable標簽是用來定義自定義控件的屬性的,我們的控件屬性都以attr形式存放在declare-styleable標簽中,format是用來形容該屬性的類型,有如下值可選:string,color,dimension,integer,enum,reference,float,boolean,fraction,flag

實現我們的View

????? 定義一個繼承自RelativeLayout的類MyCustomTitltBar,然后在他的構造方法中獲取我們自定義的控件樣式

package cn.lixyz.customviewdemo;import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.ImageButton;
import android.widget.RelativeLayout;
import android.widget.TextView;@SuppressLint("NewApi")
public class MyCustomTitleBar extends RelativeLayout {// 定義自定義控件包含的組件private TextView title;private ImageButton button;// 定義控件的屬性private String titleText;private float titleTextSize;private int titleTextColor;private Drawable titleButtonImage;// 為每個控件定義LayoutParamsprivate LayoutParams textLayoutParams;private LayoutParams buttonLayoutParams;public MyCustomTitleBar(Context context, AttributeSet attrs) {super(context, attrs);// 獲取我們定義的屬性TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.MyCustomTitleBar);titleText = array.getString(R.styleable.MyCustomTitleBar_titleText);titleTextColor = array.getColor(R.styleable.MyCustomTitleBar_titleTextColor, 0);titleTextSize = array.getDimension(R.styleable.MyCustomTitleBar_titleTextSize, 10);titleButtonImage = array.getDrawable(R.styleable.MyCustomTitleBar_titleButtonImage);// 回收,以防出錯
        array.recycle();// 新建包含的子組件title = new TextView(context);button = new ImageButton(context);// 為子組件賦值
        title.setText(titleText);title.setTextColor(titleTextColor);title.setTextSize(titleTextSize);button.setBackground(titleButtonImage);// 設置背景色setBackgroundColor(0xFF38373c);// 設置包含控件的屬性并添加到view中textLayoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);textLayoutParams.addRule(RelativeLayout.CENTER_IN_PARENT);addView(title, textLayoutParams);buttonLayoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);buttonLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);addView(button, buttonLayoutParams);}
}

  ?其中LayoutParams是用于child view(子視圖) 向 parent view(父視圖)傳達自己的意愿的一個東西

  在獲取屬性的時候,android定義的格式為控件名_屬性名 ?例如上面的MyCustomTitleBar_titleText、MyCustomTitleBar_titleTextSize

????? LayoutParams繼承于Android.View.ViewGroup.LayoutParams.?
????? LayoutParams相當于一個Layout的信息包,它封裝了Layout的位置、高、寬等信息。假設在屏幕上一塊區域是由一個Layout占領的,如果將一個View添加到一個Layout中,最好告訴Layout用戶期望的布局方式,也就是將一個認可的layoutParams傳遞進去。?
????? 可以這樣去形容LayoutParams,在象棋的棋盤上,每個棋子都占據一個位置,也就是每個棋子都有一個位置的信息,如這個棋子在4行4列,這里的“4行4列”就是棋子的LayoutParams。?
????? 但LayoutParams類也只是簡單的描述了寬高,寬和高都可以設置成三種值:?
?????????? 1,一個確定的值;?
?????????? 2,FILL_PARENT,即填滿(和父容器一樣大小);?
?????????? 3,WRAP_CONTENT,即包裹住組件就好。?

?????????? http://byandby.iteye.com/blog/816718

  TypedArray實例是個屬性的容器,通過context.obtainStyledAttributes()方法返回得到

引用我們自定的View

????? 在布局文件中引入我們自定義的控件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:custom="http://schemas.android.com/apk/res/cn.lixyz.customviewdemo"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"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="cn.lixyz.customviewdemo.MainActivity" ><cn.lixyz.customviewdemo.MyCustomTitleBarandroid:layout_width="wrap_content"android:layout_height="wrap_content"custom:titleButtonImage="@drawable/image"custom:titleText="通訊錄"custom:titleTextColor="#ffffff"custom:titleTextSize="5dp" ></cn.lixyz.customviewdemo.MyCustomTitleBar><cn.lixyz.customviewdemo.MyCustomTitleBarandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="10dp"custom:titleButtonImage="@drawable/plus"custom:titleText="微信"custom:titleTextColor="#ffffff"custom:titleTextSize="5dp" ></cn.lixyz.customviewdemo.MyCustomTitleBar><cn.lixyz.customviewdemo.MyCustomTitleBarandroid:layout_width="wrap_content"android:layout_height="30dp"android:layout_marginTop="10dp"custom:titleText="發現"custom:titleTextColor="#ffffff"custom:titleTextSize="5dp" ></cn.lixyz.customviewdemo.MyCustomTitleBar><cn.lixyz.customviewdemo.MyCustomTitleBarandroid:layout_width="wrap_content"android:layout_height="30dp"android:layout_marginTop="10dp"custom:titleText="我"custom:titleTextColor="#ffffff"custom:titleTextSize="5dp" ></cn.lixyz.customviewdemo.MyCustomTitleBar></LinearLayout>

? ? ??一定要在布局中引入我們的命名空間

  格式為:xmlns:自定義名稱="http://schemas.android.com/apk/res/包名"
  因為只有引入了我們的命名空間,才可以使用xxx:xxx格式來設置我們定義的屬性,我們平時使用的android:xx也是因為上面的xmlns:android="http://schemas.android.com/apk/res/android"
  這樣運行一下軟件查看效果

? ? ??為按鈕設置點擊事件

????? 觀察我們平時為按鈕設置點擊事件時候的方法:

bt.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stub
                }});

? ? ??我們通過按鈕的setOnClickListener方法傳入一個匿名內部類OnClickListener為按鈕設置點擊事件,我們查看OnClickListener的介紹

    /*** Interface definition for a callback to be invoked when a view is clicked.*/public interface OnClickListener {/*** Called when a view has been clicked.** @param v The view that was clicked.*/void onClick(View v);}

  

? ? ??我們也可以仿照這個形式,為我們的MyCustomTieleBar設置一個setCustomTitleBarListener,然后傳入一個內部類來讓這個按鈕的點擊調用這個類的click方法

? ? ? 修改MyCustomTitleBar:

package cn.lixyz.customviewdemo;import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageButton;
import android.widget.RelativeLayout;
import android.widget.TextView;@SuppressLint("NewApi")
public class MyCustomTitleBar extends RelativeLayout {// 定義自定義控件包含的組件private TextView title;private ImageButton button;// 定義控件的屬性private String titleText;private float titleTextSize;private int titleTextColor;private Drawable titleButtonImage;// 為每個控件定義LayoutParamsprivate LayoutParams textLayoutParams;private LayoutParams buttonLayoutParams;private customTitleBarListener listener;public interface customTitleBarListener {public void click();}public void setCustomTitleBarListener(customTitleBarListener listener) {this.listener = listener;}public MyCustomTitleBar(Context context, AttributeSet attrs) {super(context, attrs);// 獲取我們定義的屬性TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.MyCustomTitleBar);titleText = array.getString(R.styleable.MyCustomTitleBar_titleText);titleTextColor = array.getColor(R.styleable.MyCustomTitleBar_titleTextColor, 0);titleTextSize = array.getDimension(R.styleable.MyCustomTitleBar_titleTextSize, 10);titleButtonImage = array.getDrawable(R.styleable.MyCustomTitleBar_titleButtonImage);// 回收,以防出錯
        array.recycle();// 新建包含的子組件title = new TextView(context);button = new ImageButton(context);// 為子組件賦值
        title.setText(titleText);title.setTextColor(titleTextColor);title.setTextSize(titleTextSize);button.setBackground(titleButtonImage);// 設置背景色setBackgroundColor(0xFF38373c);// 設置包含控件的屬性并添加到view中textLayoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);textLayoutParams.addRule(RelativeLayout.CENTER_IN_PARENT);addView(title, textLayoutParams);buttonLayoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);buttonLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);addView(button, buttonLayoutParams);button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {listener.click();}});}
}

  這樣我們在MainActivity中就可以為按鈕設置點擊事件了

package cn.lixyz.customviewdemo;import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;public class MainActivity extends Activity {private MyCustomTitleBar addressListBar, wechatBar;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Button bt = new Button(this);bt.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stub
                }});addressListBar = (MyCustomTitleBar) findViewById(R.id.addressListBar);wechatBar = (MyCustomTitleBar) findViewById(R.id.wechatBar);addressListBar.setCustomTitleBarListener(new MyCustomTitleBar.customTitleBarListener() {@Overridepublic void click() {Toast.makeText(MainActivity.this, "通訊錄按鈕被點擊", Toast.LENGTH_SHORT).show();}});wechatBar.setCustomTitleBarListener(new MyCustomTitleBar.customTitleBarListener() {@Overridepublic void click() {Toast.makeText(MainActivity.this, "微信按鈕被點擊", Toast.LENGTH_SHORT).show();}});}}

?

?

 
?

轉載于:https://www.cnblogs.com/xs104/p/5077406.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/257906.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/257906.shtml
英文地址,請注明出處:http://en.pswp.cn/news/257906.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

android 7.0原生room,小米5S 安卓9.0 原生體驗 LineageOS16.0 ROOT

介紹ROM為第三方編譯安卓9.0 LineageOS16.0 &#xff0c;基本功能正常&#xff0c;如有其他bug&#xff0c;理性對待使用Magisk ROOT授權刷機完成后請務必到設置中手動設置當前系統時間和時區去網絡圖標上面的感嘆號和x號方法&#xff1a;打開CaptiveMgr軟件--自動彈出授權彈窗…

圖---互斥集

互斥集主要用于Kruskal算法中&#xff0c;用于求圖的最小生成樹。 互斥集主要有3個基本操作&#xff1a; 1. 初始化各個集合 Make(a)p[a] ← a 2. 查找各個集合的老祖宗 Find(a)if a p[a] : return aelse : return Find(p[a]) 3. 合并兩個集合 Union(a, b)p[Find(b)]…

Oracle配置監聽要注意的地方

昨天心血來潮&#xff0c;把Oracle的監聽都刪了&#xff0c;準備重新配一遍&#xff0c;結果弄了一天才配好&#xff0c;不過對Oracle的了解更深了一些。 對昨天的問題做一個總結&#xff1a; 1、直接在NetManager中刪掉監聽時&#xff0c;實際的監聽服務好像并沒有完全刪除&am…

signature=486e34400687432217e65e837b8e6753,PXE常見錯誤代碼表

在我們日常做無盤時&#xff0c;通常都會遇到一些這樣或那樣的問題&#xff0c;不過好在一般這些錯誤都會有些錯誤代碼&#xff0c;我們可以通過錯誤代碼查詢到一些有幫助的信息。下面是我轉載的一些PXE驅動錯誤代碼表&#xff0c;遇到PXE錯誤時&#xff0c;可查詢下看看&#…

12月25號 Category類別

Category類別 1.在已有類的基礎上進行擴展&#xff0c;無需像繼承一樣子類化&#xff0c;就可以直接添加一些方法 2.繼承不僅可以添加方法還可以添加屬性&#xff0c;類別只能添加方法 3.類別不會改變現有類的方法&#xff0c;萬一重寫&#xff0c;自己寫的優先級高 4.把類別中…

17---Net基礎加強

更新中&#xff0c;敬請期待。。。。。。。。。。。。 復習 將xml顯示到treeview 修改增加 刪除 foreach原理 深拷貝與淺拷貝 模擬數據庫及登陸 復習總結轉載于:https://www.cnblogs.com/yechangzhong-826217795/p/4157562.html

Linux系統rootpassword改動

重新啟動系統。 進入系統引導界面&#xff1a; 按下e鍵&#xff1a; 選擇第二項。內核啟動參數設置&#xff0c;按下e鍵&#xff1a; 在結尾處&#xff0c;輸入數字 1或者 英文 " single"&#xff0c;再回車&#xff1a; 按下b鍵啟動。此時以單用戶模式級別引導啟動程…

關于OC-省市區習題

對于省市區的問題&#xff0c;關鍵在于搞清楚數組嵌套字典&#xff0c;字典里面裝數組的多重嵌套關系&#xff0c;沉下心來&#xff0c;捋清楚思路&#xff0c; 實在看不懂就多打幾遍&#xff0c;這道題理解了&#xff0c;熟練了對之后學習很有好處。 代碼如下&#xff1a; NSS…

23種設計模式----------代理模式(一)

代理模式也叫委托模式。 代理模式定義&#xff1a;對其他對象提供一種代理從而控制對這個對象的訪問。就是&#xff0c;代理類 代理 被代理類&#xff0c;來執行被代理類里的方法。 一般情況下&#xff0c;代理模式化有三個角色。 1&#xff0c;抽象的主題類(或者接口) IGamePl…

(轉) Quartz學習——SSMM(Spring+SpringMVC+Mybatis+Mysql)和Quartz集成詳解(四)

http://blog.csdn.net/u010648555/article/details/60767633 當任何時候覺你得難受了&#xff0c;其實你的大腦是在進化&#xff0c;當任何時候你覺得輕松&#xff0c;其實都在使用以前的壞習慣。 通過前面的學習&#xff0c;你可能大致了解了Quartz&#xff0c;本篇博文為你打…

被流氓360設置瀏覽器主頁的解決辦法(如果你也遇到了跟我一樣的問題,不妨看一下是不是這個原因)...

最近電腦罷工&#xff0c;重裝了系統&#xff1b;很多常用軟件都不得不重新安裝&#xff0c;其實這都不是事兒&#xff0c;現在基本上都是百兆光纖了&#xff0c;下載安裝都很順溜。 瀏覽器也在安裝之列&#xff0c;因為搞開發所以谷歌火狐瀏覽器都是必裝的&#xff1b;平時基本…

BZOJ1834 [ZJOI2010]network 網絡擴容

網絡流訓練好題。。。但是要給差評&#xff01;蒟蒻表示這就是板子題&#xff0c;然后做了半個小時T T 先跑一邊最大流&#xff0c;得到第一問答案ans。 第二問&#xff1a;原先的邊不動&#xff0c;費用為0。 然后對每條邊在上面再加一條邊&#xff0c;流量為inf&#xff0c;費…

android 更新平臺,Android更新平臺架構方案

這篇文章是去年寫的&#xff0c;我們的兩款app一直這使用umeng的更新服務&#xff0c;但是16年umeng開始放棄更新服務&#xff0c;考慮到切換到其他更新平臺也會面臨這樣的問題&#xff0c;我開始著手自己搭建一個更新平臺。整體方案包含前后端&#xff0c;客戶端代碼封裝成jar…

setSignVisible的修改

store傳入accountReducer 1.從cookie中獲取id,avatar,nickname.2.createStore(reducer, initState)傳入reducer,可以在頁面中state.accountReducer.current_account獲取 const middleware routerMiddleware(browserHistory); let initState {};if(Cookie.hasItem("id&qu…

DGbroker故障切換示例

1.主庫故障 SQL> startup ORACLE instance started.Total System Global Area 1068937216 bytes Fixed Size 2260088 bytes Variable Size 910164872 bytes Database Buffers 150994944 bytes Redo Buffers 5517312 bytes ORA-00205: e…

html 自動觸發 事件,js自動觸發事件自定義事件

在有些情況下&#xff0c;我們需要程序邏輯自動觸發元素的事件&#xff0c;例如js提供了click()&#xff0c; form提供了reset(),submit()等方法&#xff01;在jquery中提供了trigger()方法幫助我們自動觸發事件&#xff0c;原理是什么呢&#xff1f;接下來讓我們一探究竟&…

Storm編程入門API系列之Storm的可靠性的ACK消息確認機制

概念&#xff0c;見博客 Storm概念學習系列之storm的可靠性 什么業務場景需要storm可靠性的ACK確認機制&#xff1f; 答&#xff1a;想要保住數據不丟&#xff0c;或者保住數據總是被處理。即若沒被處理的&#xff0c;得讓我們知道。 public void nextTuple() {num;System.out.…

關于 php mysql pdo cannot find driver 解決方案

1、下載 文件 或者 進入 在PHP源碼包中進入ext/pdo_mysql http://pecl.php.net/get/PDO_MYSQL-1.0.2.tgz 2、解壓文件tar zxvf PDO_MYSQL-1.0.2.tgz 3、配置和編譯文件cd PDO_MYSQL-1.0.2/usr/local/php/bin/phpize./configure –with-php-config/usr/local/php/bin/php-config…

iOS網絡編程開發-數據加密

iOS網絡編程開發-數據加密 一、簡單說明 1.說明 在開發應用的時候&#xff0c;數據的安全性至關重要&#xff0c;而僅僅用POST請求提交用戶的隱私數據&#xff0c;還是不能完全解決安全問題。 如&#xff1a;可以利用軟件&#xff08;比如Charles&#xff09;設置代理服務器&am…

Codeforces 821C - Okabe and Boxes

821C - Okabe and Boxes 思路&#xff1a;模擬。因為只需要比較棧頂和當前要刪除的值就可以了&#xff0c;所以如果棧頂和當前要刪除的值不同時&#xff0c;棧就可以清空了(因為下一次的棧頂不可能出現在前面那些值中)。 代碼&#xff1a; #include<bits/stdc.h> using n…