天天看點

Android開發筆記(三十六)展示類控件View/ViewGroupTextViewEditTextImageView代碼示例

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開發筆記的完整目錄