❶ android自定義控制項怎麼用
開發自定義控制項的步驟:
1、了解View的工作原理
2、 編寫繼承自View的子類
3、 為自定義View類增加屬性
4、 繪制控制項
5、 響應用戶消息
6 、自定義回調函數
一、View結構原理
Android系統的視圖結構的設計也採用了組合模式,即View作為所有圖形的基類,Viewgroup對View繼承擴展為視圖容器類。
View定義了繪圖的基本操作
基本操作由三個函數完成:measure()、layout()、draw(),其內部又分別包含了onMeasure()、onLayout()、onDraw()三個子方法。具體操作如下:
1、measure操作
measure操作主要用於計算視圖的大小,即視圖的寬度和長度。在view中定義為final類型,要求子類不能修改。measure()函數中又會調用下面的函數:
(1)onMeasure(),視圖大小的將在這里最終確定,也就是說measure只是對onMeasure的一個包裝,子類可以覆寫onMeasure()方法實現自己的計算視圖大小的方式,並通過setMeasuredDimension(width, height)保存計算結果。
2、layout操作
layout操作用於設置視圖在屏幕中顯示的位置。在view中定義為final類型,要求子類不能修改。layout()函數中有兩個基本操作:
(1)setFrame(l,t,r,b),l,t,r,b即子視圖在父視圖中的具體位置,該函數用於將這些參數保存起來;
(2)onLayout(),在View中這個函數什麼都不會做,提供該函數主要是為viewGroup類型布局子視圖用的;
3、draw操作
draw操作利用前兩部得到的參數,將視圖顯示在屏幕上,到這里也就完成了整個的視圖繪制工作。子類也不應該修改該方法,因為其內部定義了繪圖的基本操作:
(1)繪制背景;
(2)如果要視圖顯示漸變框,這里會做一些准備工作;
(3)繪制視圖本身,即調用onDraw()函數。在view中onDraw()是個空函數,也就是說具體的視圖都要覆寫該函數來實現自己的顯示(比如TextView在這里實現了繪制文字的過程)。而對於ViewGroup則不需要實現該函數,因為作為容器是「沒有內容「的,其包含了多個子view,而子View已經實現了自己的繪制方法,因此只需要告訴子view繪制自己就可以了,也就是下面的dispatchDraw()方法;
(4)繪制子視圖,即dispatchDraw()函數。在view中這是個空函數,具體的視圖不需要實現該方法,它是專門為容器類准備的,也就是容器類必須實現該方法;
(5)如果需要(應用程序調用了setVerticalFadingEdge或者setHorizontalFadingEdge),開始繪制漸變框;
(6)繪制滾動條;
從上面可以看出自定義View需要最少覆寫onMeasure()和onDraw()兩個方法。
二、View類的構造方法
創建自定義控制項的3種主要實現方式:
1)繼承已有的控制項來實現自定義控制項: 主要是當要實現的控制項和已有的控制項在很多方面比較類似, 通過對已有控制項的擴展來滿足要求。
2)通過繼承一個布局文件實現自定義控制項,一般來說做組合控制項時可以通過這個方式來實現。
注意此時不用onDraw方法,在構造廣告中通過inflater載入自定義控制項的布局文件,再addView(view),自定義控制項的圖形界面就載入進來了。
3)通過繼承view類來實現自定義控制項,使用GDI繪制出組件界面,一般無法通過上述兩種方式來實現時用該方式。
三、自定義View增加屬性的兩種方法:
1)在View類中定義。通過構造函數中引入的AttributeSet 去查找XML布局的屬性名稱,然後找到它對應引用的資源ID去找值。
案例:實現一個帶文字的圖片(圖片、文字是onDraw方法重繪實現)
public class MyView extends View {
private String mtext;
private int msrc;
public MyView(Context context) {
super(context);
}
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
int resourceId = 0;
int textId = attrs.getAttributeResourceValue(null, "Text",0);
int srcId = attrs.getAttributeResourceValue(null, "Src", 0);
mtext = context.getResources().getText(textId).toString();
msrc = srcId;
}
@Override
protected void onDraw(Canvas canvas) {
Paint paint = new Paint();
paint.setColor(Color.RED);
InputStream is = getResources().openRawResource(msrc);
Bitmap mBitmap = BitmapFactory.decodeStream(is);
int bh = mBitmap.getHeight();
int bw = mBitmap.getWidth();
canvas.drawBitmap(mBitmap, 0,0, paint);
//canvas.drawCircle(40, 90, 15, paint);
canvas.drawText(mtext, bw/2, 30, paint);
}
}
布局文件:
<?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"
android:orientation="vertical" >
<com.example.myimageview2.MyView
android:id="@+id/myView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
Text="@string/hello_world"
Src="@drawable/xh"/>
</LinearLayout>
屬性Text, Src在自定義View類的構造方法中讀取。
2)通過XML為View注冊屬性。與Android提供的標准屬性寫法一樣。
案例: 實現一個帶文字說明的ImageView (ImageView+TextView組合,文字說明,可在布局文件中設置位置)
public class MyImageView extends LinearLayout {
public MyImageView(Context context) {
super(context);
}
public MyImageView(Context context, AttributeSet attrs) {
super(context, attrs);
int resourceId = -1;
TypedArray typedArray = context.obtainStyledAttributes(attrs,
R.styleable.MyImageView);
ImageView iv = new ImageView(context);
TextView tv = new TextView(context);
int N = typedArray.getIndexCount();
for (int i = 0; i < N; i++) {
int attr = typedArray.getIndex(i);
switch (attr) {
case R.styleable.MyImageView_Oriental:
resourceId = typedArray.getInt(
R.styleable.MyImageView_Oriental, 0);
this.setOrientation(resourceId == 1 ? LinearLayout.HORIZONTAL
: LinearLayout.VERTICAL);
break;
case R.styleable.MyImageView_Text:
resourceId = typedArray.getResourceId(
R.styleable.MyImageView_Text, 0);
tv.setText(resourceId > 0 ? typedArray.getResources().getText(
resourceId) : typedArray
.getString(R.styleable.MyImageView_Text));
break;
case R.styleable.MyImageView_Src:
resourceId = typedArray.getResourceId(
R.styleable.MyImageView_Src, 0);
iv.setImageResource(resourceId > 0 ?resourceId:R.drawable.ic_launcher);
break;
}
}
addView(iv);
addView(tv);
typedArray.recycle();
}
}
attrs.xml進行屬性聲明, 文件放在values目錄下
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="MyImageView">
<attr name="Text" format="reference|string"></attr>
<attr name="Oriental" >
<enum name="Horizontal" value="1"></enum>
<enum name="Vertical" value="0"></enum>
</attr>
<attr name="Src" format="reference|integer"></attr>
</declare-styleable>
</resources>
MainActivity的布局文件:先定義命名空間 xmlns:uview="http://schemas.android.com/apk/res/com.example.myimageview2" (com.example.myimageview2為你
在manifest中定義的包名)
然後可以像使用系統的屬性一樣使用:uview:Oriental="Vertical"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:uview="http://schemas.android.com/apk/res/com.example.myimageview2"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" />
<com.example.myimageview2.MyImageView
android:id="@+id/myImageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
uview:Text="這是一個圖片說明"
uview:Src="@drawable/tw"
uview:Oriental="Vertical">
</com.example.myimageview2.MyImageView>
</LinearLayout>
四、控制項繪制 onDraw()
五、
六:自定義View的方法
onFinishInflate() 回調方法,當應用從XML載入該組件並用它構建界面之後調用的方法
onMeasure() 檢測View組件及其子組件的大小
onLayout() 當該組件需要分配其子組件的位置、大小時
onSizeChange() 當該組件的大小被改變時
onDraw() 當組件將要繪制它的內容時
onKeyDown 當按下某個鍵盤時
onKeyUp 當松開某個鍵盤時
onTrackballEvent 當發生軌跡球事件時
onTouchEvent 當發生觸屏事件時
onWindowFocusChanged(boolean) 當該組件得到、失去焦點時
onAtrrachedToWindow() 當把該組件放入到某個窗口時
onDetachedFromWindow() 當把該組件從某個窗口上分離時觸發的方法
onWindowVisibilityChanged(int): 當包含該組件的窗口的可見性發生改變時觸發的方法
❷ 和利時怎麼自定義控制項
1、了解View的工作原理。
2、編寫繼承自View的子類,為自定義View類增加屬性。
3、繪制控制項,響應用戶消息,自定義回調函數,這樣就可以自定義控制項了。
❸ c# 用戶自定義控制項 方法
1)在FrmChild中
……
publicpartialclassFrmChild:Form
{
privateCtrlAm_ctrl;
//添加一個新的構造函數,原來的構造函數保留
publicFrmChild(CtrlActrl):this()
{
this.m_ctrl=ctrl;
}
//假設FrmChild上有一個按鈕button1,點擊button1後,調用CtrlA.M()
privatevoidbutton1_Click(objectsender,EventArgse)
{
this.m_ctrl.M();
}
}
2)在控制項CtrlA中,點擊按鈕後顯示子窗體FrmChild的代碼如下
FrmChildf=newFrmChild(this);//注意:在CtrlA控制項中,this是CtrlA的實例!
f.Show();
======補充回答=========
OpenChild(Typetype)
{
Formfrm=(Form)Acivator.CreateInstance(type,newobject[]{this});
frm.ShowDialog(this);
}
❹ C# 訪問 自定義添加控制項 的值
TextBoxtb001=null;
Control[]controls=this.Controls.Find("tb001",true);
if(controls.Length>0)
{
tb001=controls[0]asTextBox;
}
MessageBox.Show(tb001==null?"null":tb001.Text);
試試看行不行
❺ iOS 怎麼在子頁面怎麼得到tabbarcontroller上的自定義控制項
iOS 在子頁面得到tabbarcontroller上的自定義控制項的方法:
一般地自定義一個控制項有兩種選擇:
完全重寫
繼承重寫
兩種方式各有所長,通常主要是通過繼承重寫來自定義TabBarController。
在自定義UITabBarController之前,首先我們必須了解UITabBarController結構與其各個相關類的關系:
TabBarController
TabBar
TabButton
ViewController
其中,TabButton是一個雙態的Button(選中和未選中)。TabBar是TabButton的容器,負責TabButton的排布和互斥,保證同時只有一個Button為選中態。TabBarController包含了TabBar,並管理這一個ViewController的棧,在TabBar上的按鈕點擊時對棧上的ViewController位置進行相應的調整,從而保持TabBar和ViewController棧之間的一致性。
通過上面對系統原生的UITabBarView結構分析可知,需要創建三個類:
TabBarController
TabBar
Button
項目結構圖示:
❻ 怎麼在C#代碼中訪問自定義控制項的子控制項
方法一你直接給每個TextBlock命名,比如按命名為txtBlk,那麼在c#里你就可以直接這么賦值了,txtBlk.Text
=
"Hello";
❼ c#動態載入用戶自定義控制項,怎麼對該進行訪問
給這個用戶控制項加一個public方法,例如:public SetLabel(string label1Text,string label2Text)
在這個方法里去設置label1、label2的text,那麼你在實例化了用戶控制項之後,就可以通過調用這個方法去設置label1、label2的text。這是舉例說明,你如果需要設置其他屬性,都是可以通過自己控制參數去設置
❽ ASP。NET自定義控制項中寫了一個方法,在引用這個控制項的父頁面如何調用這個方法
沒有這么用的。在控制項內部寫方法是為了這個控制項服務,那麼就定義一個事件來完成相應的操作,或者設定一個屬性,和方法關聯,在父頁面調用屬性或者觸發事件
❾ winform中怎樣訪問自定義控制項中的控制項
可是現在關鍵的是這個自定義控制項就是這個主窗體的一部分,你不能在給他添加show了 回答: 把第一句聲明Form去掉,最後一句:主窗體.tabControl1.Controls.Add(tbPage);
這句不加你直接寫成Form1.tabControl1.Controls.Add(tbPage);他會提示tabcontrol要求引用,如果你之寫成Form1 form;不能使用未賦值的變數form 回答: 好好看書吧 追問: 到底能不能給個答案啊,我急著用呢,你說的方法都行不通,我都試過好多次了 回答: 別的窗體代碼添加用要添加的對象調用,自身添加用this指針調用。 追問: 能說清楚點嗎,這個this怎麼調用啊,我調用完了之後也沒反應啊,我快沒積分了就不能追問了,我很著急用這個 回答: 比如你要在主窗體中添加,在主窗體的後台代碼中寫上this.tabControl1.Controls.Add(tbPage); 追問: 大哥,我服你了,你到現在都沒有看明白我問的是啥意思吧,我問的是怎麼在自定義控制項中給主窗體添加tabpage,而不是在主窗體中給主窗體添加tabpage, 回答: 「別的窗體代碼添加用要添加的對象調用」在主窗體中聲明自定義控制項的時候從構造函數里傳入主窗體的對象,然後調用該對象的方法進行操作,或者定義一個靜態類,在靜態類中定義一個Form的靜態對象,把主窗體傳給靜態對象,要操作的時候調用靜態類的靜態對象,建議你好好看書,把基礎的東西搞清楚,不明白給你舉個例子: //生成按鈕單擊事件(主窗體的方法)
private void btnCreat_Click(object sender, EventArgs e){if (ValidateCard()){CardRecord.CardList = CreateCard(Convert.ToInt32(cboCreateCount.Text));
new CardInfoForm(lvCard).Show();
this.Close();
} } //創建ListView,用來接收傳入的ListView對象(傳入的窗體)
ListView lvCard = new ListView(); public CardInfoForm(ListView listView){InitializeComponent();
//傳入主窗體的ListView