View/ViewGroup
View是單個視圖,所有的控件類都是從它派生出來;而ViewGroup是個視圖組織,所有的布局視圖類都是從它派生出來。由于View和ViewGroup是基類,是以很少會直接使用,偶爾用到的場景,主要有如下幾個:
1、頁面上需要單獨顯示一條橫線或者豎線。如果填充圖檔顯然不夠經濟,最簡單的做法,就是在xml布局中增加一個View控件,高度或寬度設定為1dp,背景顔色設定為線條顔色,這樣便實作了單獨顯示線條的需求。
2、點選事件的處理函數onClick(View v),這裡面我們要調用View的getId方法擷取發生點選事件的控件id,進而進行該控件對應的點選處理。
3、在代碼中設定某控件為可見或不可見或消失,此時需要使用View類的三個變量,分别是View.VISIBLE、View.INVISIBLE和View.GONE。
TextView
TextView是最基礎的文本顯示控件了,基本屬性如text、textColor、textSize、textDirection、textStyle、textAlignment就不多說了(一般隻需設定前三個屬性,後面三個屬性用得很少),下面隻列出幾個特殊場景在實際中的運用:
1、聊天室或者文字直播間效果。聊天室視窗的高度是固定的,新的文字消息總是加入到視窗末尾,同時視窗内部的文本整體向上滾動,而視窗的大小保持不變、位置也保持不變。
在XML布局檔案中實作時,可設定如下屬性:
gravity : 指定文本的對齊方式,一般取值“left|bottom”,表示靠左對齊且靠下對齊。
lines : 指定文本的行數。
maxLines : 指定文本的最大行數。
scrollbars : 指定滾動條的方向,一般取值vertical,如不指定将不顯示滾動條。注意該屬性隻能在xml中設定。
在代碼中實作時,可調用如下方法:
setGravity : 設定文本的對齊方式。
setLines : 設定文本的行數。
setMaxLines : 設定文本的最大行數。
setMovementMethod : 設定文本移動的方式,一般取值“new ScrollingMovementMethod()”,如不設定将無法拉動文本。注意該方法隻能在代碼中調用。
需要注意的是,scrollbars隻能在xml中設定,而無法通過代碼設定。反過來,setMovementMethod隻能在代碼中設定,而無法通過xml設定。是以要實作聊天室效果必須同時修改xml布局檔案與代碼。
2、在文字周圍放置圖檔。通過線上性布局内部放置ImageView控件也能實作,但顯然不如在TextView控件内部加入圖檔來得友善。
在XML布局檔案中實作時,可設定如下屬性:
drawableTop : 指定文本上方的圖形。
drawableBottom : 指定文本下方的圖形。
drawableLeft : 指定文本左邊的圖形。
drawableRight : 指定文本右邊的圖形。
drawablePadding : 指定圖形與文本的間距。
在代碼中實作時,可調用如下方法:
setCompoundDrawables : 設定文本周圍的圖形。該方法有四個參數,分别表示左邊、上方、右邊、下方的圖形。
setCompoundDrawablePadding : 設定圖形與文本的間距。
3、對該控件(或視圖)截圖。需要先設定繪圖緩存可用,然後取出該控件的繪圖緩存完成截圖操作。
該操作必須通過代碼完成,相關方法如下:
setDrawingCacheEnabled : 設定繪圖緩存的可用狀态。true表示打開,false表示關閉。
isDrawingCacheEnabled : 判斷該控件的繪圖緩存是否可用。
setDrawingCacheQuality : 設定繪圖緩存的品質。
getDrawingCache : 擷取該控件的繪圖緩存結果,傳回值為Bitmap類型
setDrawingCacheBackgroundColor : 設定繪圖緩存的背景顔色。可能大家很奇怪為何還要該方法,其實是因為繪圖緩存預設背景色是黑色,如果不提前設定緩存的背景色的話,截圖的結果就是黑乎乎一片,是以需要将背景色設定為預設顔色(通常是白色)。
其實截圖操作适用于大多數控件和視圖,因為這幾個方法來自于View類,是以凡是繼承自View的控件和視圖都是可以截圖的。
EditText
EditText是文本輸入框,與輸入有關的屬性說明如下:
在XML布局檔案中指定:
inputType : 指定輸入的文本類型。常用的取值說明包括:text表示普通文本,textPassword表示文本密碼,textEmailAddress表示郵件位址,number表示數字,numberPassword表示數字密碼,phone表示電話和手機号碼。
maxLength : 指定文本允許輸入的最大長度。該屬性無法通過代碼設定。
hint : 指定提示文本。
textColorHint : 指定提示文本的顔色。
在代碼中設定:
setInputType : 設定輸入的文本類型。如果要隐藏密碼注意要設定“InputType.TYPE_CLASS_TEXT|InputType.TYPE_TEXT_VARIATION_PASSWORD”,如果要顯示密碼則設定“InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD”。
setHint : 設定提示文本。
setHintTextColor : 設定提示文本的顔色。
在錄入使用者資訊時(比如輸入姓名、密碼等等),EditText輸入Enter鍵,常常不要換行而是讓光标直接跳到下一個編輯框。這個場景說起來簡單,開發過程中就分解為三個功能:
1、監控使用者目前輸入了Enter鍵。該功能有兩種實作方式:
方式一:給編輯框注冊一個OnKeyListener監聽器(setOnKeyListener方法),當檢測到Enter鍵(keyCode == 66)時,觸發光标跳轉操作;
方式二:給編輯框注冊一個TextWatcher監聽器(addTextChangedListener方法),當檢測到文本發生變化并找到回車換行符時,觸發光标跳轉操作;
2、保持目前控件不換行,依舊單行顯示。該功能有兩種實作方式:
方式一:在布局檔案的EditText節點中加入singleLine屬性,但該方式隻在視覺上起作用,真正的字元串還是帶有回車換行符;
android:singleLine="true"
方式二:去掉編輯框文本中的回車符和換行符,示例代碼如下:
String str = et_this.getText().replace("\r", "").replace("\n", "");
et_this.setText(str);
3、光标跳到下個編輯框,并自動挪到編輯框文本末尾。該功能有兩種實作方式:
方式一:使用EditText的setSelection方法,示例代碼如下:
et_next.requestFocus();
et_next.setSelection(et_next.getText().length());
方式二:使用Selection的setSelection方法,示例代碼如下:
et_next.requestFocus();
Editable edit = et_next.getText();
Selection.setSelection(edit, edit.length());
注意控件之間切換光标要使用requestFocus方法,不能使用setFocusable方法(該方法隻能切換焦點,不能切換光标)。
EditText還有一個需要特殊處理的地方,就是自動關閉軟鍵盤。一般我們希望點選其它控件時,原輸入框的軟鍵盤就要自動消失,可惜Android不是這樣處理。于是我們得通過輸入法工具類InputMethodManager來協助,該類的對象從系統服務Context.INPUT_METHOD_SERVICE中擷取。下面是自動關閉軟鍵盤的兩種方法:
1、調用toggleSoftInput方法,該方法會關閉所有控件彈出的軟鍵盤;
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
//軟鍵盤如果已經打開則關閉之
if (imm.isActive() == true) {
imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
}
複制
2、調用hideSoftInputFromWindow方法,該方法隻關閉指定EditText控件彈出的軟鍵盤;
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(et_server.getWindowToken(), 0);
複制
ImageView
ImageView是圖形顯示控件,與圖形顯示有關的屬性說明如下:
在XML布局檔案中指定:
scaleType : 指定圖形的拉伸類型。常用的取值說明包括:fitXY表示拉伸圖檔正好填滿視圖(圖檔可能被拉伸變形),fitStart表示拉伸圖檔使之位于視圖上部,fitCenter表示拉伸圖檔使之位于視圖中間,fitEnd表示拉伸圖檔使之位于視圖下部,center表示保持圖檔原尺寸使之位于視圖中間,centerCrop表示拉伸圖檔并使視圖位于圖檔中間,centerInside表示使圖檔位于視圖中間(隻壓不拉)。以上方式隻有fitXY不按比例拉伸,其他都要按比例拉伸。另外注意centerInside,當圖檔尺寸大于視圖時,centerInside等同于fitCenter;當圖檔尺寸小于視圖時,centerInside等同于center。
src : 指定圖形來源,src圖形按照scaleType拉伸。
background : 指定圖形背景。注意背景圖不按比例拉伸,其實背景預設以fitXY方式拉伸。
在代碼中設定:
setScaleType : 設定圖形的拉伸類型。
setImageAlpha : 設定圖形的透明度。
setImageBitmap : 設定圖形的Bitmap對象。
setImageDrawable : 設定圖形的Drawable對象。
setImageResource : 設定圖形的資源ID。
代碼示例
文字直播室的代碼例子如下:
import com.example.exmsimplewidget.R;
import java.text.SimpleDateFormat;
import java.util.Date;
import android.app.Activity;
import android.os.Bundle;
import android.text.method.ScrollingMovementMethod;
import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class LiveTextActivity extends Activity implements OnClickListener {
private TextView tv_live;
private EditText et_news;
private Button btn_publish;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_live_text);
tv_live = (TextView) findViewById(R.id.tv_live);
et_news = (EditText) findViewById(R.id.et_news);
btn_publish = (Button) findViewById(R.id.btn_publish);
btn_publish.setOnClickListener(this);
tv_live.setGravity(Gravity.LEFT|Gravity.BOTTOM);
tv_live.setLines(20);
tv_live.setMaxLines(20);
tv_live.setMovementMethod(new ScrollingMovementMethod());
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.btn_publish) {
String desc = String.format("%s\n直播員 %s:%s",
tv_live.getText(), getNowDateTime(), et_news.getText());
tv_live.setText(desc);
}
}
private String getNowDateTime() {
SimpleDateFormat s_format = new SimpleDateFormat("HH:mm:ss");
Date d_date = new Date();
String s_date = "";
s_date = s_format.format(d_date);
return s_date;
}
}
複制
編輯框回車跳轉的代碼例子如下:
import com.example.exmsimplewidget.R;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.text.Editable;
import android.text.InputType;
import android.text.Selection;
import android.text.TextWatcher;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnKeyListener;
import android.widget.Button;
import android.widget.EditText;
public class EnterInfoActivity extends Activity {
private final static String TAG = "EnterInfoActivity";
private EditText et_user, et_password, et_job;
private Button btn_cancel, btn_ok;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_enter_info);
et_user = (EditText) findViewById(R.id.et_user);
et_password = (EditText) findViewById(R.id.et_password);
et_job = (EditText) findViewById(R.id.et_job);
btn_cancel = (Button) findViewById(R.id.btn_cancel);
btn_ok = (Button) findViewById(R.id.btn_ok);
et_user.setInputType(InputType.TYPE_CLASS_TEXT);
et_password.setInputType(InputType.TYPE_CLASS_TEXT|InputType.TYPE_TEXT_VARIATION_PASSWORD);
et_job.setInputType(InputType.TYPE_CLASS_TEXT);
et_user.setOnKeyListener(new MyKeyListener(et_password, mUserRefresh));
et_password.addTextChangedListener(new MyTextWatcher(et_password, et_job));
et_job.addTextChangedListener(new MyTextWatcher(et_job, btn_ok));
}
private final Handler mHandler = new Handler();
private Runnable mUserRefresh = new Runnable() {
@Override
public void run() {
et_user.setText(et_user.getText().toString().replace("\r", "").replace("\n", ""));
}
};
class MyKeyListener implements OnKeyListener {
private View mNextView = null;
private Runnable mRun = null;
public MyKeyListener(View vNext, Runnable run) {
super();
if (vNext != null) {
mNextView = vNext;
}
mRun = run;
}
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if(keyCode == 66 && mNextView != null) {
mHandler.postDelayed(mRun, 50);
mNextView.requestFocus();
if (mNextView instanceof EditText) {
EditText et = (EditText)mNextView;
et.setSelection(et.getText().length());
}
}
return false;
}
}
class MyTextWatcher implements TextWatcher {
private EditText mThisView = null;
private View mNextView = null;
public MyTextWatcher(EditText vThis, View vNext) {
super();
mThisView = vThis;
if (vNext != null) {
mNextView = vNext;
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
Log.d(TAG, "et_user.getText()="+et_user.getText());
String str = s.toString();
if (str.indexOf("\r") >= 0 || str.indexOf("\n") >= 0) {
Log.d(TAG, "afterTextChanged mThisView.getId()="+mThisView.getId()
+", mNextView.getId()="+mNextView.getId());
mThisView.setText(str.replace("\r", "").replace("\n", ""));
if (mNextView != null) {
mNextView.requestFocus();
if (mNextView instanceof EditText) {
EditText et = (EditText)mNextView;
Editable edit = et.getText();
Selection.setSelection(edit, edit.length());
}
}
}
}
}
}
複制
點此檢視Android開發筆記的完整目錄