Android 第八課 創建自定義控件

常用控件和布局的繼承結構,如下圖:

(待續。。。。)

所有的控件都是直接或間接繼承自View的所用的所有布局都是直接或間接繼承自ViewGroup的,View是Android中最基本的一種UI組件,它可以在屏幕上繪制一塊矩形區域,并能響應這塊區域的各種事件,ViewGroup是一中特殊的View,它可以包含很多的子View和子ViewGroup,是一個用于放置控件和布局的容器

我們可以利用上面的繼承結構來創建自定義控件,創建自定義控件的兩種簡單方法如下所示。

我們先創建一個UICustomViews項目。

1、引入布局

Android系統已經給每個活動提供了標題欄功能,但我們決定先不使用它,而是創建一個自定義的標題欄。

只需要兩個Button和一個TextView,然后在布局中擺好就可以了,但是一般我們的程序中可能有很多個活動都需要這樣的標題欄,如果在每個活動的布局中都編寫一遍同樣的標題欄代碼,明顯的就會導致代碼的大量重復,這個時候,我們可以引入布局的方式來解決這個問題。我們在layout目錄下新建一個布局文件title.xml,代碼如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="wrap_content"><Buttonandroid:id="@+id/title_back"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:layout_margin="5dp"android:background="#000"android:text="Back"android:textColor="#f00"/><TextViewandroid:id="@+id/title_text"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_gravity="center"android:layout_weight="1"android:gravity="center"android:background="#000"android:text="Title Text"android:textColor="#f5f"android:textSize="24sp"/><Buttonandroid:id="@+id/title_edit"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:layout_margin="5dp"android:background="#000"android:text="Edit"android:textColor="#f00"/>
</LinearLayout>

我們在LinearLayout中分別加入了兩個Batton和一個TextView,左邊的Button可用于返回,右邊的Button可用于編輯,中間的TextView則可以用來顯示一段標題文本。熟悉一下屬性,其中android:backgroud用于為布局或控件指定一個背景,可以使用顏色或者是照片來進行填充。

另外在兩個Button中我們都使用了android:layout_margin這個屬性,它可以指定控件在上下左右方向上偏移的距離,當然也可以使用android:layout_marginLeft或者android:layout_marginTop等屬性來單獨指定控件在某個方向上偏移的距離。

那么標題欄文件title.xml我們已經編寫完成,那我們如何在程序中使用這個標題欄呢,修改acticity_main.xml中的代碼,如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context="com.example.uicustomviews.MainActivity"> <include layout="@layout/title"/></LinearLayout>

我們只需要通過一行include語句將標題欄布局引進來就可以了。

但是最后,不要忘了在MainActivity中將系統自帶的標題欄隱藏掉,代碼如下:

package com.example.uicustomviews;import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main); ActionBar actionBar = getSupportActionBar();if(actionBar != null){actionBar.hide();}}
}

我們調用了getSupportActionBar()方法來獲得ActionBar的實例,然后再調用ActionBar的hide()方法將標題欄隱藏起來。

使用這種方式,不管有多少布局需要標題欄,只需要一行include語句就可以了。

測試用例如下:


2、創建自定義組件

引入布局的技巧確實解決了重復編寫布局代碼的問題,但是如果布局中有一些控件要求能夠響應事件,我們還是需要在每個活動中為這些控件單獨編寫一次事件注冊的代碼。比如說,標題欄的返回按鈕,不管在哪一個活動中,都是用來銷毀當前活動。為了不增加重復代碼,我們使用自定義控件的方式來解決。

新建TitleLayout繼承自LinearLayout,讓它成為我們自定義的標題欄控件,代碼如下:

package com.example.uicustomviews;import android.content.Context;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.widget.LinearLayout;public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);ActionBar actionBar = getSupportActionBar();if(actionBar != null){actionBar.hide();}}public class TitleLayout  extends  LinearLayout {public TitleLayout(Context context, AttributeSet attrs) {super(context, attrs);LayoutInflater.from(context).inflate(R.layout.title, this);}}
}

我們重寫了LinearLayout中帶有兩個參數的構造函數,在布局文件中引入TitleLayout控件就會調用這個構造函數,然后在構造函數中需要對標題進行動態加載,這就是要LayoutInflator來實現了。通過LayoutInflator的from()方法可以構建出一個LayoutInflater對象,然后調用inflator()方法就可以動態加載一個布局文件,inflate()接收兩個參數,第一個參數是要加載的布局文件的id,我們傳入的是R.layout.title,第二個參數是給加載好的布局再添加一個父布局,我們指定為TitleLayout,于是直接傳入this。

現在自定義控件已經建好,3、我們還需要在布局文件中添加這個自定義控件,修改activity_main.xml中的代碼,如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent" ><com.example.uicustomviews.TitleLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content" /></LinearLayout>

重新運行程序!

為標題欄的按鈕注冊點擊事件,修改TitleLayout中的代碼,如下:

package com.example.uicustomviews;import android.app.Activity;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.Toast;public class TitleLayout extends LinearLayout {public TitleLayout(Context context, AttributeSet attrs) {super(context, attrs);LayoutInflater.from(context).inflate(R.layout.title, this); Button titleBack = (Button) findViewById(R.id.title_back);Button titleEdit = (Button) findViewById(R.id.title_edit);titleBack.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {((Activity) getContext()).finish();}});titleEdit.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {Toast.makeText(getContext(), "You clicked Edit button",Toast.LENGTH_SHORT).show();}});}}

首先通過findViewById()方法得到按鈕的實例,然后分別調用setOnClickListener()方法給兩個按鈕注冊了點擊事件,當點擊返回按鈕時,銷毀當前的活動,當點擊編輯按鈕時彈出一段文本。

效果如下圖:


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

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

相關文章

figma下載_搬到Figma對我意味著什么

figma下載A couple of years ago, amidst the boom of new design and prototyping software, I was pretty reluctant to fight on the Figma/Sketch cold war. I was working on a relatively small design team and, after years helping to design products, well sold on …

解決IE中img.onload失效的方法

解決IE中img.onload失效的方法 - CoffeeCats IT Blog - IT博客http://www.cnitblog.com/CoffeeCat/archive/2008/02/01/39533.htmlFirefox、Google Chrome不存在問題&#xff01;為什么onload沒有被IE調用呢&#xff1f;因為IE會緩存圖片&#xff0c;第2次加載的圖片&#xff0…

Android 第九課 常用控件-------ListView

ListView允許用戶通過手指上下滑動的方式將屏幕外的數據滾動到屏幕內&#xff0c;同時屏幕上原有數據將會滾動出屏幕。 1、ListView簡單用法 如何將ListView將你要顯示的大量內容關聯起來呢&#xff1f;這是個很重要的問題。 1、首先我們必須先將數據提供好&#xff0c;因為你的…

Singleton patterns 單件(創建型模式)

1、模式分類 1.1 從目的來看&#xff1a; ? – 創建型&#xff08;Creational&#xff09;模式&#xff1a;負責對象創建。 ? – 結構型&#xff08;Structural&#xff09;模式&#xff1a;處理類與對象間的組合。 ? – 行為型&#xff08;Behavioral&…

Android 第十一課 SQlite 數據庫存儲

Android 為了讓我們能夠更加方便的管理數據庫&#xff0c;特意提供了一個SQLiteOpenHelper幫助類&#xff0c;通過借助這個類就可以非常簡單的對數據庫進行創建和升級。 SQLiteOpenHelper是一個抽象類&#xff0c;我們要創建一個自己的幫助類去繼承它。SQLiteOpenHelper有兩個抽…

淺析SQL Server 2005中的主動式通知機制

一、引言 在開發多人同時訪問的Web應用程序&#xff08;其實不只這類程序&#xff09;時&#xff0c;開發人員往往會在緩存策略的設計上狠下功夫。這是因為&#xff0c;如果將這種環境下不常變更的數據臨時存放在應用程序服務器或是用戶機器上的話&#xff0c;可以避免頻繁地往…

Android 第十二課 使用LitePal操作數據庫(記得閱讀最后面的注意事項哦)

一、LitePal簡介 1、(新建項目LitePalTest)正式接觸第一個開源庫---LitePalLitePal是一款開源的Android 數據庫框架&#xff0c;它采用了對象關系映射&#xff08;ORM&#xff09;的模式。2、配置LitePal&#xff0c;編輯app/build.gradle文件&#xff0c;在dependencies閉包中…

listview頻繁刷新報錯

在Android編程中使用Adapter時&#xff0c;偶爾會出現如下錯誤&#xff1a;The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI t…

Android 第十三課 SharedPreferences存儲

SharedPreferences是使用鍵值對的方式來存儲數據的。當保存一條數據時&#xff0c;需要給這條數據提供一個對應的鍵&#xff0c;這樣在讀取數據的時候就可以通過這個鍵把相應的值取出來。而且支SharedPreferences還支持多種不同的數據類型存儲&#xff0c;例如&#xff1a;如果…

DSP的Gel作用

轉自&#xff1a;http://blog.csdn.net/azhgul/article/details/6660960最近剛在研究Davinci系&#xff0c;特此MARK下&#xff0c;以資后續學習之用。 DSP的Gel作用 1 GEL文件基本作用 當CCSStudio啟動時&#xff0c;GEL文件加載到PC機的內存中&#xff0c;如果定義了StartUp(…

解決關于登錄校園網顯示不在IP段的問題方案(要看注意事項哦!)

有時&#xff0c;登錄校園網&#xff0c;賬號和密碼都顯示正確&#xff0c;但是卻顯示出“賬號只能在指定IP段登錄”的問題。 那我們就提供了一個解決方案&#xff1a; 使用WinR,并在輸入框&#xff0c;輸入cmd命令&#xff1a;&#xff08;如下&#xff09;接著輸入&#xff1…

jquery插件編寫

jQuery為開發插件提拱了兩個方法&#xff0c;分別是&#xff1a; jQuery.fn.extend(object); jQuery.extend(object); jQuery.extend(object); 為擴展jQuery類本身.為類添加新的方法。可以理解為添加靜態方法。是全局的&#xff08;位于jQuery命名空間內部的函數&#xff09;…

gtk/Glade編程 編譯命令不成功 解決方法

摘自&#xff1a;http://blog.chinaunix.net/uid-26746982-id-3433656.html 當我們編寫gtk/glade程序&#xff0c;gcc編譯時&#xff0c;用如下命令&#xff1a; #gcc -o server server.c pkg-config --cflags --libs gtk-2.0 報錯&#xff1a;/tmp/ccoXadAd.o: In function …

Android 第十五課 如何使用LitePal從SQLite數據庫中刪除數據(十四課用來保留講解如何向SQLite數據庫中存入數據)

使用LitePal刪除數據的方式主要有兩種&#xff0c;第一種就是直接調用已存對象的delete()方法&#xff0c;所謂已存儲對象就是調用過save()方法的對象&#xff0c;或者說是通過LitePal提供的查詢API查出來的對象&#xff0c;都是可以直接使用delete方法來刪除對象的。這是比較簡…

頁面返回頂部(方法比較)

下面就說下簡單的返回頂部效果的代碼實現&#xff0c;附注釋說明。 1. 最簡單的靜態返回頂部&#xff0c;點擊直接跳轉頁面頂部&#xff0c;常見于固定放置在頁面底部返回頂部功能 方法一&#xff1a;用命名錨點擊返回到頂部預設的id為top的元素 html代碼 <a href"#top…

Android 第十六課 使用LitePal查詢數據

LitePal在查詢API方面做了非常多的優化&#xff0c;基本上可以滿足絕大多數場景的查詢需求&#xff0c;并且代碼也十分整潔。 例如我們需要查詢表中的所有數據&#xff1a; List<books> DataSupport.findAll(Book.class); 沒有冗長的參數列表&#xff0c;只需要調用一下…

linux創建桌面圖標,和開始菜單欄圖標

轉自&#xff1a;http://blog.csdn.net/qq_25773973/article/details/50514767 ###環境&#xff1a;Mint17&#xff0c;&#xff08;其他類似的linux系統是一樣的&#xff09; 如果開始菜單有圖標&#xff0c;創建桌面圖標很簡單&#xff0c;右鍵添加到桌面即可。 如果沒有&am…

ScrollView中使用ListView

轉自 http://blog.csdn.net/fzh0803/article/details/7971391 由于scrollview和listview不能直接共存&#xff0c;在scrollview中直接使用lsitview的話只會顯示一個條目&#xff0c;要使他們共存&#xff0c; 據我所知&#xff0c;有三種方法&#xff1a; 1。如果listview的高度…

Android 第十四課 使用LitePal添加數據(更新數據)

我們注意到當你登錄一個app&#xff0c;是不是需要先注冊呢&#xff1f;&#xff0c;所謂注冊&#xff0c;簡單地來理解是不是就是把輸入框中地數據傳入數據庫中呢&#xff1f; 這里我們設置簡單一點&#xff0c;注冊的信息只包括兩項&#xff0c;一項是用戶名&#xff0c;另一…

微信公眾平臺的服務號和訂閱號

微信公眾平臺 服務號 訂閱號 作者&#xff1a;方倍工作室 地址&#xff1a;http://www.cnblogs.com/txw1958/p/ServiceNumber-subscriptionNumber.html 什么是服務號&#xff1f; 服務號給企業和組織提供更強大的業務服務與用戶管理能力&#xff0c;幫助企業快速實現全新的公眾…