Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android 界面編程 探險(一)

Android 界面編程 探險(一)

編輯:關於Android編程

Android應用大部分UI組件都放在android.widget包及其子包、android.view包及其子包中,所有UI組件都繼承了View類,Android采用“組合器”設計模式來設計View和ViewGroup(ViewGroup是View的子類),Android圖形用戶界面的組件層次如下圖:

 

\

 

在此強烈建議閱讀官方文檔(Documentation for Android SDK,打開index.html,Develop -> API Guides / Reference)。

Android中布局建議采用XML布局文件和Java代碼(變化多、行為控制復雜的用Java代碼)混合控制UI界面

下面我們開始Android界面編程的大探險(一些簡單的屬性,例如layout_width、layout_height等,下面將不再贅述)。

1.UI控件-布局管理器

 

所有布局管理器都是ViewGroup的子類,Android布局管理器類圖(StarUML繪制)如下:

\

 

1)線性布局LinearLayout

android:orientation=""		設置布局管理器內組件的排列方式,horizontal水平、vertical垂直(默認)
android:gravity=""		用於控制它所包含的子元素的對齊方式
android:layout_gravity=""	設置該子元素在父容器中的對齊方式

2)表格布局TableLayout

通過添加TableRow、其他組件控制表格行數、列數
..		添加1個表格行
android:shrinkColumns="1"	指定第2列允許收縮
android:stretchColumns="2"	指定第3列可以被拉伸
android:stretchColumns="1,2"	指定第2、3列可以被拉伸
android:collapseColumns="1"	指定第2列被隱藏

3)幀布局FrameLayout

android:layout_gravity=""

4)相對布局RelativeLayout

android:gravity=""
android:ignoreGravity=""		設置哪個組件不受gravity影響
android:layout_centerHorizontal=""	定義該組件位於父容器水平居中
android:layout_centerInParent=""	定義該組件位於父容器中間
android:layout_above="@id/abc"		定義該組件位於abc組件的上方
android:layout_below="@id/abc"		定義該組件位於abc組件的下方
android:layout_toLeftOf="@id/abc"	定義該組件位於abc組件的左邊
android:layout_alignLeft="@id/abc"	控制該組件位於abc的左邊界對齊
android:layout_alignParentLeft="@id/abc"  控制該組件是否與布局容器左邊對齊

5)網格布局GridLayout

GridLayout是Android4.0新增的布局管理器

android:alignmentMode=""	設置GridLayout采用的對齊模式
android:columnCount="4"		設置網格列數量
android:columnOrderPreserved=""	設置網格容器是否保留列序號
android:rowCount=""		設置網格行數量
android:rowOrderPreserved=""	設置網格容器是否保留行序號
android:useDefaultMargins=""	設置GridLayout是否使用默認的頁邊距

6)絕對布局AbsoluteLayout

(已過時)

 

 

2.UI組件-TextView及其子類

 

TextView及其子類類圖如下:

\

TextView和EditText最大區別在於TextView不允許用戶編輯文本內容。

1)TextView屬性

android:drawableEnd="@drawable/icon"	設置文本框結尾處繪制圖片
android:ellipsize="middle"				設置中間省略 
android:textAllCaps="true"				設置所有字母大寫
android:autoLink="email|phone"			對郵件、電話增加鏈接

android:shadowColor="#0000ff"			設置文字陰影
android:shadowDx="10.0"
android:shadowDy="8.0"
android:shadowRadius="3.0"

android:password="true"				設置密碼框

2)CheckedTextView屬性

		通過checkMark設置該文本框的勾選圖標

3)圓角邊框、漸變背景的TextView

main.xml
<!--?xml version="1.0" encoding="utf-8"?-->
<linearlayout android:layout_height="match_parent" android:layout_width="match_parent" android:orientation="vertical" xmlns:android="http://schemas.android.com/apk/res/android">
<textview android:background="@drawable/bg_border" android:layout_height="wrap_content" android:layout_width="match_parent" android:text="帶邊框的文本">
<textview android:background="@drawable/bg_border2" android:layout_height="wrap_content" android:layout_width="match_parent" android:text="圓角邊框、漸變背景的文本">
</textview></textview></linearlayout>

bg_border.xml
<!--?xml version="1.0" encoding="utf-8"?--><shape xmlns:android="http://schemas.android.com/apk/res/android">
</stroke></solid></shape>

bg_border2.xml
<!--?xml version="1.0" encoding="utf-8"?--><shape android:shape="rectangle" xmlns:android="http://schemas.android.com/apk/res/android">
   	<corners android:bottomleftradius="5px" android:bottomrightradius="20px" android:topleftradius="20px" android:toprightradius="5px">
	<stroke android:color="#f0f" android:width="4px"> 
	<gradient android:centercolor="#0f0" android:endcolor="#00f" android:startcolor="#f00" android:type="sweep">
</gradient></stroke></corners></shape>

4)EditText組件的用法

<edittext android:hint="請填寫登錄帳號" android:layout_height="wrap_content" android:layout_width="match_parent" android:selectallonfocus="true">

<edittext android:inputtype="numberPassword" android:layout_height="wrap_content" android:layout_width="match_parent"></edittext></edittext>

5)Button組件的用法

<button android:layout_height="wrap_content" android:layout_width="wrap_content" android:shadowcolor="#aa5" android:shadowdx="5" android:shadowdy="5" android:shadowradius="1" android:text="文字帶陰影的按鈕">	
</button><button android:background="@drawable/red" android:layout_height="wrap_content" android:layout_width="wrap_content" android:text="普通按鈕">
</button><button android:background="@drawable/button_selector" android:layout_height="wrap_content" android:layout_width="wrap_content" android:text="帶文字的圖片按鈕">


button_selector.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">
	<item android:drawable="@drawable/red" android:state_pressed="true">
	<item android:drawable="@drawable/purple" android:state_pressed="false">
</item></item></selector></button>

6)點9圖片

實現只縮放圖片中的某個部分的效果(可用於屏幕適配)
draw9patch工具 --> sdk\tools\draw9patch.bat
\

7)單選按鈕(RadioButton)與復選框(CheckBox)的用法

RadioButton與CheckBox的不同在於一組RadioButton只能選中其中一個,因此RadioButton常與RadioGroup一起使用,用於定義一組單選按鈕。如下定義了一個讓用戶選擇的輸入界面:

main.xml

 

<tablelayout android:layout_height="match_parent" android:layout_width="match_parent" android:orientation="vertical" xmlns:android="http://schemas.android.com/apk/res/android">
	
	<tablerow>
		<radiogroup android:id="@+id/rg" android:layout_gravity="center_horizontal" android:orientation="horizontal">
			<radiobutton android:checked="true" android:id="@+id/javaee" android:layout_height="wrap_content" android:layout_width="wrap_content" android:text="JavaEE">
			<radiobutton android:id="@+id/android" android:layout_height="wrap_content" android:layout_width="wrap_content" android:text="Android">
		</radiobutton></radiobutton></radiogroup>
	</tablerow>	
	
	<tablerow>
		<linearlayout android:layout_gravity="center_horizontal" android:layout_height="wrap_content" android:layout_width="wrap_content" android:orientation="vertical">
			<checkbox android:checked="true" android:layout_height="wrap_content" android:layout_width="wrap_content" android:text="A">
			<checkbox android:layout_height="wrap_content" android:layout_width="wrap_content" android:text="B">
			<checkbox android:layout_height="wrap_content" android:layout_width="wrap_content" android:text="C">
		</checkbox></checkbox></checkbox></linearlayout>
	</tablerow>
	
	<textview android:id="@+id/show" android:layout_height="wrap_content" android:layout_width="wrap_content">
		
</textview></tablelayout>
CheckButtonTest.java

下面添加事件監聽采用了“委托式”事件處理機制(當事件源上發生事件時,該事件會激發該事件源上的監聽器的特定方法)。

public class CheckButtonTest extends Activity {
	private RadioGroup rg;
	private TextView show;
	@Override
	public void onCreate(Bundle savedInstanceState) {
		
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		
		rg = (RadioGroup) findViewById(R.id.rg);
		show = (TextView) findViewById(R.id.show);
		// 為RadioGroup組件的OnCheck事件綁定事件監聽器
		rg.setOnCheckedChangeListener(new OnCheckedChangeListener() {
			@Override
			public void onCheckedChanged(RadioGroup group, int checkedId) {
				// 根據用戶勾選的單選按鈕來動態改變tip字符串的值
				String tip = checkedId == R.id.javaee ? "您最熱愛的技術是JavaEE": "您最熱愛的技術是Android";
				// 修改show組件中的文本。
				show.setText(tip);
			}
		});
	}
}

8)其他

狀態開關按鈕(ToggleButton)

開關(Switch)

時鐘(AnalogClock和DigitalClock)

計時器(Chronometer)

詳細使用方法請查閱Android官方文檔,這裡不再贅述。
 

 

3.UI組件-ImageView及其子類

 

ImageView及其子類類圖如下:

\

ImageView繼承View組件,任何Drawable對象都可以使用ImageView來顯示。

1)圖片浏覽器 - 實現增大降低透明度、下一張功能

main.xml

<linearlayout android:layout_height="match_parent" android:layout_width="match_parent" android:orientation="vertical" xmlns:android="http://schemas.android.com/apk/res/android">
	
	<linearlayout android:gravity="center" android:layout_height="wrap_content" android:layout_width="match_parent" android:orientation="horizontal"><button android:id="@+id/maxus" android:layout_height="wrap_content" android:layout_width="wrap_content" android:text="增大透明度"></button><button android:id="@+id/minus" android:layout_height="wrap_content" android:layout_width="wrap_content" android:text="降低透明度"></button><button android:id="@+id/next" android:layout_height="wrap_content" android:layout_width="wrap_content" android:text="下一張">		
	
	
	<imageview android:id="@+id/image1" android:layout_height="240px" android:layout_width="match_parent" android:scaletype="fitCenter" android:src="@drawable/image1">
		
	<imageview android:background="#00f" android:id="@+id/image2" android:layout_height="120dp" android:layout_margintop="10dp" android:layout_width="120dp">
		
</imageview></imageview></button></linearlayout></linearlayout>
ImageViewTest.java
public class ImageViewTest extends Activity {
	
	// 一個訪問圖片的數組
	int[] images = new int[]{
		R.drawable.image1,
		R.drawable.image2,
		R.drawable.image3,
		R.drawable.image4,
		R.drawable.image5,
	};
	// 默認顯示的圖片
	int currentImg = 2;
	// 圖片的初始透明度
	private int alpha = 255;
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		final Button maxus = (Button) findViewById(R.id.maxus);
		final Button minus = (Button) findViewById(R.id.minus);
		final ImageView image1 = (ImageView) findViewById(R.id.image1);
		final ImageView image2 = (ImageView) findViewById(R.id.image2);
		final Button next = (Button) findViewById(R.id.next);
		// 查看下一張圖片的監聽器
		next.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				// 設置ImageView顯示下一張圖片
				image1.setImageResource(images[++currentImg % images.length]);
			}
		});
		// 改變圖片透明度的方法
		OnClickListener listener = new OnClickListener() {
			@Override
			public void onClick(View v) {
				if (v == maxus) {
					alpha += 20;
				}
				if (v == minus) {
					alpha -= 20;
				}
				if (alpha >= 255) {
					alpha = 255;
				}
				if (alpha <= 0) {
					alpha = 0;
				}
				// 改變圖片的透明度
				image1.setAlpha(alpha);
			}
		};
		// 為兩個按鈕添加監聽器
		maxus.setOnClickListener(listener);
		minus.setOnClickListener(listener);
		image1.setOnTouchListener(new OnTouchListener() {
			@Override
			public boolean onTouch(View view, MotionEvent event) {
				BitmapDrawable bitmapDrawable = (BitmapDrawable) image1
						.getDrawable();
				// 獲取第一個圖片顯示框中的位圖
				Bitmap bitmap = bitmapDrawable.getBitmap();
				// bitmap圖片實際大小與第一個ImageView的縮放比例
				double scale = bitmap.getWidth() / 320.0;
				// 獲取需要顯示的圖片的開始點
				int x = (int) (event.getX() * scale);
				int y = (int) (event.getY() * scale);
				if (x + 120 > bitmap.getWidth()) {
					x = bitmap.getWidth() - 120;
				}
				if (y + 120 > bitmap.getHeight()) {
					y = bitmap.getHeight() - 120;
				}
				// 顯示圖片的指定區域
				image2.setImageBitmap(Bitmap.createBitmap(bitmap, x, y, 120, 120));
				image2.setAlpha(alpha);
				return false;
			}
		});
	}
}

 

 

4.UI組件-AdapterView及其子類(一)

 

AdapterView繼承了ViewGroup,它的本質是容器。AdapterView顯示的多個列表項由Adapter提供,調用AdapterView的setAdapter(Adapter)方法設置Adapter即可。

AdapterView派生了三個子類:AbsListView、AbsSpinner、AdapterViewAnimator,這三個子類也是抽象的,實際使用往往采用它們的子類。

AdapterView及其子類類圖如下:

\

Adapter及其子類類圖如下:

\

1)基於數組的ListView

\res\layout\main.xml


	
	


\res\values\arrays.xml


	
		Java
		JavaEE
		Android
	

2)使用ArrayAdapter創建ListView

布局文件如下:

\res\layout\main.xml
<linearlayout android:layout_height="fill_parent" android:layout_width="fill_parent" android:orientation="vertical" xmlns:android="http://schemas.android.com/apk/res/android">
	<listview android:divider="#f00" android:dividerheight="2px" android:headerdividersenabled="false" android:id="@+id/list" android:layout_height="wrap_content" android:layout_width="fill_parent">
</listview></linearlayout>

\res\layout\array_item.xml
<textview android:id="@+id/TextView" android:layout_height="wrap_content" android:layout_width="match_parent" android:padding="10px" android:shadowcolor="#f0f" android:shadowdx="4" android:shadowdy="4" android:shadowradius="2" android:textsize="24dp" xmlns:android="http://schemas.android.com/apk/res/android"></textview>

ArrayAdapterTest.java

public class ArrayAdapterTest extends Activity {
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		ListView list = (ListView) findViewById(R.id.list);
		String[] arr = { "Java", "JavaEE", "Android" };
		// 創建ArrayAdapter對象
		ArrayAdapter adapter = new ArrayAdapter(this, R.layout.array_item, arr);
		// 設置Adapter
		list.setAdapter(adapter);
	}
}
另外,基於ListActivity實現列表,只需要去除ListView布局文件,然後修改ArrayAdapterTest.java如下:
public class ArrayAdapterTest extends ListActivity {
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		//無須使用布局文件
		String[] arr = { "Java", "JavaEE", "Android" };
		// 創建ArrayAdapter對象
		ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_multiple_choice, arr);
		// 設置Adapter
		setListAdapter(adapter);
	}
}

3)繼承BaseAdapter實現ListView

繼承BaseAdapter可取得對Adapter最大的控制權。

布局文件如下:

main.xml

 

<linearlayout android:layout_height="match_parent" android:layout_width="match_parent" android:orientation="vertical" xmlns:android="http://schemas.android.com/apk/res/android">
	<listview android:id="@+id/myList" android:layout_height="match_parent" android:layout_width="match_parent">
</listview></linearlayout>
adapter_main.xml
<linearlayout android:layout_height="wrap_content" android:layout_width="match_parent" android:orientation="vertical" xmlns:android="http://schemas.android.com/apk/res/android">
    <linearlayout android:gravity="center_vertical" android:layout_height="55dp" android:layout_marginleft="5dp" android:layout_width="match_parent" android:orientation="vertical">
        <textview android:id="@+id/tv_name" android:layout_height="wrap_content" android:layout_width="wrap_content" android:singleline="true" android:text="哈哈哈" android:textsize="16sp">
    </textview></linearlayout>
</linearlayout>
下面來看看具體代碼實現,首先設置全局變量和編寫實體類
/**
 * 設置全局變量
 * 注意:需要在AndroidManifest.xml中做配置
 */
public class MyApplication extends Application{
	private static Context context;//全局的上下文
	//app的入口函數
	@Override
	public void onCreate() {
		super.onCreate();
		//初始化COntext
		context = this;
	}
	/**
	 * 獲取全局的上下文
	 * @return
	 */
	public static Context getContext(){
		return context;
	}
}

 

 

/**
 * 實體類
 */
public class AppInfo {
	private String name;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
}

 

然後再來看看BaseAdapterTest.java

 

public class BaseAdapterTest extends Activity {
	private ArrayList list ;
	private ListView myList;
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		myList = (ListView) findViewById(R.id.myList);

		... // 解析json或者xml,獲取請求的數據

		myList.setAdapter(new MyAdapter(list));
	}
}
MyAdapter.java(已做優化處理)
public class MyAdapter extends BaseAdapter {

	private ArrayList list;
	public MyAdapter(ArrayList list) {
		super();
		this.list = list;
	}
	/**
	 * 設置條目個數
	 */
	@Override
	public int getCount() {
		return list.size();
	}
	/**
	 * 獲取對應條目的數據
	 */
	@Override
	public Object getItem(int position) {
		return null;
	}
	/**
	 * 獲取對應條目的id
	 */
	@Override
	public long getItemId(int position) {
		return 0;
	}
	/**
	 * 設置條目樣式
	 */
	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		if(convertView==null){
			convertView = View.inflate(MyApplication.getContext(), R.layout.adapter_main, null);
		}
		ViewHolder holder = ViewHolder.getHolder(convertView);
		
		// 獲取實體類,設置數據
		AppInfo appInfo = list.get(position);
		holder.tv_name.setText(appInfo.getName());
		return convertView;
	}
	/**
	 * 利用ViewHolder進行性能優化
	 */
	static class ViewHolder{
		TextView tv_name;
		public ViewHolder(View convertView){
			tv_name = (TextView) convertView.findViewById(R.id.tv_name);
		}
		public static ViewHolder getHolder(View convertView){
			ViewHolder holder = (ViewHolder) convertView.getTag();
			if(holder==null){
				holder = new ViewHolder(convertView);
				convertView.setTag(holder);
			}
			return holder;
		}
	}
}

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved