1.自定義BaseAdapter,而後綁定ListView的最簡單例子
先看看咱們要實現的效果圖:
一個很簡單的ListView,本身寫下Item,而後加載點數據這樣~ 下面貼下關鍵代碼:java
Animal.java:android
public class Animal { private String aName; private String aSpeak; private int aIcon; public Animal() { } public Animal(String aName, String aSpeak, int aIcon) { this.aName = aName; this.aSpeak = aSpeak; this.aIcon = aIcon; } public String getaName() { return aName; } public String getaSpeak() { return aSpeak; } public int getaIcon() { return aIcon; } public void setaName(String aName) { this.aName = aName; } public void setaSpeak(String aSpeak) { this.aSpeak = aSpeak; } public void setaIcon(int aIcon) { this.aIcon = aIcon; } }
AnimalAdapter.java:自定義的BaseAdapter:canvas
public class AnimalAdapter extends BaseAdapter { private LinkedList<Animal> mData; private Context mContext; public AnimalAdapter(LinkedList<Animal> mData, Context mContext) { this.mData = mData; this.mContext = mContext; } @Override public int getCount() { return mData.size(); } @Override public Object getItem(int position) { return null; } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { convertView = LayoutInflater.from(mContext).inflate(R.layout.item_list_animal,parent,false); ImageView img_icon = (ImageView) convertView.findViewById(R.id.img_icon); TextView txt_aName = (TextView) convertView.findViewById(R.id.txt_aName); TextView txt_aSpeak = (TextView) convertView.findViewById(R.id.txt_aSpeak); img_icon.setBackgroundResource(mData.get(position).getaIcon()); txt_aName.setText(mData.get(position).getaName()); txt_aSpeak.setText(mData.get(position).getaSpeak()); return convertView; } }
最後是MainActivity.java:app
public class MainActivity extends AppCompatActivity { private List<Animal> mData = null; private Context mContext; private AnimalAdapter mAdapter = null; private ListView list_animal; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mContext = MainActivity.this; list_animal = (ListView) findViewById(R.id.list_animal); mData = new LinkedList<Animal>(); mData.add(new Animal("狗說", "你是狗麼?", R.mipmap.ic_icon_dog)); mData.add(new Animal("牛說", "你是牛麼?", R.mipmap.ic_icon_cow)); mData.add(new Animal("鴨說", "你是鴨麼?", R.mipmap.ic_icon_duck)); mData.add(new Animal("魚說", "你是魚麼?", R.mipmap.ic_icon_fish)); mData.add(new Animal("馬說", "你是馬麼?", R.mipmap.ic_icon_horse)); mAdapter = new AnimalAdapter((LinkedList<Animal>) mData, mContext); list_animal.setAdapter(mAdapter); } }
好的,自定義BaseAdapter以及完成數據綁定就是這麼簡單~
別問我拿示例的代碼,剛開始學就會寫出這些代碼,我只是演示下流程,讓你們熟悉 熟悉而已~另外,也是爲下面的屬性驗證作準備~
2.表頭表尾分割線的設置:
listview做爲一個列表控件,他和普通的列表同樣,能夠本身設置表頭與表尾: 以及分割線,可供咱們設置的屬性以下:ide
footerDividersEnabled:是否在footerView(表尾)前繪製一個分隔條,默認爲true
headerDividersEnabled:是否在headerView(表頭)前繪製一個分隔條,默認爲true
divider:設置分隔條,能夠用顏色分割,也能夠用drawable資源分割
dividerHeight:設置分隔條的高度
翻遍了了API發現並無能夠直接設置ListView表頭或者表尾的屬性,只能在Java中寫代碼 進行設置了,可供咱們調用的方法以下:佈局
addHeaderView(View v):添加headView(表頭),括號中的參數是一個View對象
addFooterView(View v):添加footerView(表尾),括號中的參數是一個View對象
addHeaderView(headView, null, false):和前面的區別:設置Header是否能夠被選中
addFooterView(View,view,false):同上
對了,使用這個addHeaderView方法必須放在listview.setAdapter前面,不然會報錯。
post
代碼實現:
先編寫下表頭與表尾的佈局:
view_header.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" android:orientation="vertical" android:gravity="center"> <TextView android:layout_width="match_parent" android:layout_height="48dp" android:textSize="18sp" android:text="表頭" android:gravity="center" android:background="#43BBEB" android:textColor="#FFFFFF"/> </LinearLayout>
MainActivty.java:ui
public class MainActivity extends AppCompatActivity implements AdapterView.OnItemClickListener{ private List<Animal> mData = null; private Context mContext; private AnimalAdapter mAdapter = null; private ListView list_animal; private LinearLayout ly_content; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mContext = MainActivity.this; list_animal = (ListView) findViewById(R.id.list_animal); //動態加載頂部View和底部View final LayoutInflater inflater = LayoutInflater.from(this); View headView = inflater.inflate(R.layout.view_header, null, false); View footView = inflater.inflate(R.layout.view_footer, null, false); mData = new LinkedList<Animal>(); mData.add(new Animal("狗說", "你是狗麼?", R.mipmap.ic_icon_dog)); mData.add(new Animal("牛說", "你是牛麼?", R.mipmap.ic_icon_cow)); mData.add(new Animal("鴨說", "你是鴨麼?", R.mipmap.ic_icon_duck)); mData.add(new Animal("魚說", "你是魚麼?", R.mipmap.ic_icon_fish)); mData.add(new Animal("馬說", "你是馬麼?", R.mipmap.ic_icon_horse)); mAdapter = new AnimalAdapter((LinkedList<Animal>) mData, mContext); //添加表頭和表尾須要寫在setAdapter方法調用以前!!! list_animal.addHeaderView(headView); list_animal.addFooterView(footView); list_animal.setAdapter(mAdapter); list_animal.setOnItemClickListener(this); } @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Toast.makeText(mContext,"你點擊了第" + position + "項",Toast.LENGTH_SHORT).show(); } }
好的,代碼仍是比較簡單的,從上面咱們看出來一個要注意的問題,就是:
添加表頭表尾後,咱們發現positon是從表頭開始算的,就是你添加的第一個數據原本的 postion 是 0,可是此時卻變成了 1,由於表頭也算!!this
GridView與ListView的用法基本一致,不一樣的只是佈局。當咱們打開手機,應用會以宮格顯示,那就是GridView。
以代碼形式展現給你們,適配器使用SimpleAdapter,熟悉了適配器的用法,就只須要注意幾個GridView的屬性便可。
Activity類
public class MainActivity extends Activity { private GridView gridView; private List<Map<String, Object>> dataList; private SimpleAdapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); gridView = (GridView) findViewById(R.id.gridview); //初始化數據 initData(); String[] from={"img","text"}; int[] to={R.id.img,R.id.text}; adapter=new SimpleAdapter(this, dataList, R.layout.gridview_item, from, to); gridView.setAdapter(adapter); gridView.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { AlertDialog.Builder builder= new AlertDialog.Builder(MainActivity.this); builder.setTitle("提示").setMessage(dataList.get(arg2).get("text").toString()).create().show(); } }); } void initData() { //圖標 int icno[] = { R.drawable.i1, R.drawable.i2, R.drawable.i3, R.drawable.i4, R.drawable.i5, R.drawable.i6, R.drawable.i7, R.drawable.i8, R.drawable.i9, R.drawable.i10, R.drawable.i11, R.drawable.i12 }; //圖標下的文字 String name[]={"時鐘","信號","寶箱","秒鐘","大象","FF","記事本","書籤","印象","商店","主題","迅雷"}; dataList = new ArrayList<Map<String, Object>>(); for (int i = 0; i <icno.length; i++) { Map<String, Object> map=new HashMap<String, Object>(); map.put("img", icno[i]); map.put("text",name[i]); dataList.add(map); } } }
**GridView主佈局文件activity_main.xml** <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#000" tools:context="com.example.l7.MainActivity" > <GridView android:id="@+id/gridview" android:layout_width="match_parent" android:layout_height="wrap_content" android:columnWidth="80dp" android:stretchMode="spacingWidthUniform" android:numColumns="3" /> </LinearLayout>
列表項佈局gridview_item.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:orientation="vertical" > <ImageView android:id="@+id/img" android:layout_width="60dp" android:layout_height="60dp" android:layout_marginTop="10dp" android:src="@drawable/ic_launcher" /> <TextView android:id="@+id/text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="2dp" android:layout_gravity="center" android:textColor="#FFF" android:text="文字" /> </LinearLayout>
效果圖
樣式是指爲 View 或窗口指定外觀和格式的屬性集合。樣式能夠指定高度、填充、字體顏色、字號、背景色等許多屬性。 樣式是在與指定佈局的 XML 不一樣的 XML 資源中進行定義。
Android 中的樣式與網頁設計中層疊樣式表的原理相似 — 您能夠經過它將設計與內容分離。
例如,經過使用樣式,您能夠將如下佈局 XML:
<TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:textColor="#00FF00" android:typeface="monospace" android:text="@string/hello" /> 簡化成這個樣子: <TextView style="@style/CodeFont" android:text="@string/hello" />
佈局 XML 中全部與樣式有關的屬性都已移除,並置於一個名爲 CodeFont 的樣式定義內,而後經過 style 屬性加以應用。 您會在下文中看到對該樣式的定義。
主題是指對整個 Activity 或應用而不是對單個 View(如上例所示)應用的樣式。 以主題形式應用樣式時,Activity 或應用中的每一個視圖都將應用其支持的每一個樣式屬性。 例如,您能夠 Activity 主題形式應用同一 CodeFont 樣式,以後該 Activity 內的全部文本都將具備綠色固定寬度字體。
定義樣式
要建立一組樣式,請在您的項目的 res/values/ 目錄中保存一個 XML 文件。 可任意指定該 XML 文件的名稱,但它必須使用 .xml 擴展名,而且必須保存在 res/values/ 文件夾內。
該 XML 文件的根節點必須resources。
對於您想建立的每一個樣式,向該文件添加一個 style 元素,該元素帶有對樣式進行惟一標識的 name 屬性(該屬性爲必需屬性)。而後爲該樣式的每一個屬性添加一個 item 元素,該元素帶有聲明樣式屬性以及屬性值的 name(該屬性爲必需屬性)。 根據樣式屬性,item 的值能夠是關鍵字字符串、十六進制顏色值、對另外一資源類型的引用或其餘值。如下是一個包含單個樣式的示例文件:
<?xml version="1.0" encoding="utf-8"?> <resources> <style name="CodeFont" parent="@android:style/TextAppearance.Medium"> <item name="android:layout_width">fill_parent</item> <item name="android:layout_height">wrap_content</item> <item name="android:textColor">#00FF00</item> <item name="android:typeface">monospace</item> </style> </resources> resources
元素的每一個子項都會在編譯時轉換成一個應用資源對象,該對象可由 style>元素的 name 屬性中的值引用。 可從 XML 佈局以 @style/CodeFont 形式引用該示例樣式(如上文引言中所示)。
style 元素中的 parent 屬性是可選屬性,它指定應做爲此樣式所繼承屬性來源的另外一樣式的資源 ID。 若是願意,您可在隨後替換這些繼承的樣式屬性。
切記,在 XML 中定義您想用做 Activity 或應用主題的樣式與定義視圖樣式的方法徹底相同。 諸如上文所定義的樣式可做爲單個視圖的樣式加以應用,也可做爲整個 Activity 或應用的主題加以應用。 後文將闡述如何爲單個視圖應用樣式或如何以應用主題形式應用樣式。
設置樣式的方法有兩種:
若是是對單個視圖應用樣式,請爲佈局 XML 中的 View 元素添加 style 屬性。
或者,若是是對整個 Activity 或應用來應用樣式,請爲 Android 清單中的 activity 或 application 元素添加 android:theme 屬性。
當您對佈局中的單個 View 應用樣式時,該樣式定義的屬性只應用於該 View。 若是對 ViewGroup 應用樣式,子 View 元素將不會繼承樣式屬性 — 只有被您直接應用樣式的元素纔會應用其屬性。 不過,您能夠經過以主題形式應用樣式,使所應用的樣式做用於全部 View 元素。
要以主題形式應用樣式定義,您必須在 Android 清單中將樣式應用於 Activity 或應用。 若是您這樣作,Activity 或應用內的每一個 View 都將應用其支持的每一個屬性。 例如,若是您對某個 Activity 應用前面示例中的 CodeFont 樣式,則全部支持這些文本樣式屬性的 View 元素也會應用這些屬性。 任何不支持這些屬性的 View 都會忽略這些屬性。 若是某個 View 僅支持部分屬性,將只應用這些屬性。
對視圖應用樣式
爲 XML 佈局中的視圖設置樣式的方法以下:
< TextView style="@style/CodeFont" android:text="@string/hello" />
如今該 TextView 將按照名爲 CodeFont 的樣式的定義設置樣式(請參閱上文定義樣式中的示例)。
注:style 屬性不使用 android: 命名空間前綴。
對 Activity 或應用應用主題
要爲您的應用的全部 Activity 設置主題,請打開 AndroidManifest.xml 文件並application 標記,在其中加入帶樣式名稱的 android:theme 屬性。 例如:
若是您只想對應用中的一個 Activity 應用主題,則改成給
正如 Android 提供了其餘內建資源同樣,有許多預約義主題可供您使用,可免於自行編寫。 例如,您可使用 Dialog 主題,爲您的 Activity 賦予相似對話框的外觀:
或者,若是您但願背景是透明的,則可以使用 Translucent 主題:
<activity android:theme="@android:style/Theme.Translucent"> 若是您喜歡某個主題,但想作些調整,只需將該主題添加爲您的自定義主題的 parent。 例如,您能夠像下面這樣對傳統明亮主題進行修改,使用您本身的顏色: <color name="custom_theme_color">#b0b0ff</color> <style name="CustomTheme" parent="android:Theme.Light"> <item name="android:windowBackground">@color/custom_theme_color</item> <item name="android:colorBackground">@color/custom_theme_color</item> </style>
(請注意,此處顏色須要以單獨資源形式提供,由於 android:windowBackground 屬性僅支持對另外一資源的引用;不一樣於 android:colorBackground,沒法爲其提供顏色字面量。)
如今,在 Android 清單內使用 CustomTheme 替代 Theme.Light:
根據平臺版本選擇主題
新版本的 Android 可爲應用提供更多主題,您可能但願在這些平臺上運行時可使用這些新增主題,同時仍可兼容舊版本。 您能夠經過自定義主題來實現這一目的,該主題根據平臺版本利用資源選擇在不一樣父主題之間切換。
圖片的處理包括如下:
1, 縮放
2, 傾斜
3, 旋轉
4, 縮放+
5, 平移
6, 鏡像
代碼以下:
package com.mike.activity; import java.io.FileNotFoundException; import android.app.Activity; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.BitmapFactory.Options; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Matrix; import android.graphics.Paint; import android.net.Uri; import android.os.Bundle; import android.util.Log; import android.view.Display; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ImageView; public class ImageDemoActivity extends Activity implements OnClickListener { /** Called when the activity is first created. */ public static String TAG = "IMAGE"; public static int REQUEST_CODE = 0; private ImageView mImageShow; private ImageView mImageAltered; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Button p_w_picpathSelectBtn = (Button) findViewById(R.id.p_w_picpathSelectBtn); mImageShow = (ImageView) findViewById(R.id.p_w_picpathShow); mImageAltered = (ImageView) findViewById(R.id.p_w_picpathAltered); p_w_picpathSelectBtn.setOnClickListener(this); } public void onClick(View v) { // TODO Auto-generated method stub Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);// 啓動照片Gallery startActivityForResult(intent, 0); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent intent) { // TODO Auto-generated method stub super.onActivityResult(requestCode, resultCode, intent); if (resultCode == RESULT_OK) {// 操做成功 Uri imgFileUri = intent.getData();// 得到所選照片的信息 Log.d(TAG, "imgFileUri is :" + imgFileUri); // 因爲返回的圖像可能太大而沒法徹底加載到內存中。系統有限制,須要處理。 Display currentDisplay = getWindowManager().getDefaultDisplay(); int defaultHeight = currentDisplay.getHeight(); int defaultWidth = currentDisplay.getWidth(); BitmapFactory.Options bitmapFactoryOptions = new BitmapFactory.Options(); bitmapFactoryOptions.inJustDecodeBounds = false;// /只是爲獲取原始圖片的尺寸,而不返回Bitmap對象 // 註上:If set to true, the decoder will return null (no bitmap), but // the out... fields will still be set, // allowing the caller to query the bitmap without having to // allocate the memory for its pixels try { Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver() .openInputStream(imgFileUri), null, bitmapFactoryOptions); int outHeight = bitmapFactoryOptions.outHeight; int outWidth = bitmapFactoryOptions.outWidth; int heightRatio = (int) Math.ceil((float) outHeight / defaultHeight); int widthRatio = (int) Math.ceil((float) outWidth / defaultWidth); if (heightRatio > 1 || widthRatio > 1) { if (heightRatio > widthRatio) { bitmapFactoryOptions.inSampleSize = heightRatio; } else { bitmapFactoryOptions.inSampleSize = widthRatio; } } bitmapFactoryOptions.inJustDecodeBounds = false; bitmap = BitmapFactory.decodeStream(getContentResolver() .openInputStream(imgFileUri), null, bitmapFactoryOptions); mImageShow.setImageBitmap(bitmap); // /* // * 在位圖上繪製位圖 // */ // // Bitmap bitmapAltered = Bitmap.createBitmap(bitmap.getWidth(), // bitmap.getHeight(), bitmap.getConfig()); // // Canvas canvas = new // Canvas(bitmapAltered);//bitmap提供了畫布,只在此提供了大小尺寸,偏移後並未有背景顯示出來 // // // Paint paint = new Paint(); // // canvas.drawBitmap(bitmap, 0, 0, paint);//繪製的圖片和以前的如出一轍 // // mImageAltered.setImageBitmap(bitmapAltered); /* * 使用矩陣 */ Bitmap bitmapAltered = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), bitmap.getConfig());// 缺點是限定畫布大小,處理後的圖片可能被截斷,可引入矩陣構造方法,動態設定畫布大小 Canvas canvas = new Canvas(bitmapAltered);// bitmap提供了畫布,只在此提供了大小尺寸,偏移後並未有背景顯示出來, Paint paint = new Paint(); Matrix matrix = new Matrix(); // 1:縮放 // matrix.setValues(new float[] {//涉及線性代數的知識,能夠翻翻相乘的基礎知識 // 1,0,0,//算出x的值 // 0,1,0,//算出y的值 // 0,0,1//二維圖用不到 // }); // 2:傾斜 // matrix.setValues(new float[] {//涉及線性代數的知識,能夠翻翻相乘的基礎知識 // 1,.5f,0,//算出x的值,x,y值相關 // 0,1,0,//算出y的值 // 0,0,1//二維圖用不到 // }); // 3:旋轉 // matrix.setRotate(45);//設置旋轉角度,(0,0)點,順時針旋轉45度 // 4,縮放plus:使用Matrix類方法//須要修改畫布寬度>1.5倍* 原始寬度 // matrix.setScale(1.5f, 1); // 5,平移 // matrix.setTranslate(10, 0); // 6,鏡像 // eg1:x軸鏡像 // matrix.setScale(-1, 1);//向左繪製,原始圖片沿y軸對稱 // matrix.postTranslate(bitmap.getWidth(), 0);//注意是post即後移動 // eg2:y軸鏡像 matrix.setScale(1, -1);// 向上繪製,原始圖片沿x軸對稱,圖像在第四象限 matrix.postTranslate(0, bitmap.getHeight());// 注意是post即後移動 //~optimize~由於指定畫布大小bitmapAltered,因此處理後的圖片可能被截斷,能夠經過矩陣動態改變bitmapAltered大小 //eg: matrix.setRotate(degrees, px, py) //bitmapAltered = Bitmap.createBitmap(source, x, y, width, height, m, filter);//顯然矩陣影響其大小 // // 注:for more details :Wikipedia Transformation Matrix // http://en.wikipedia.org/wiki/Transformation_matrix canvas.drawBitmap(bitmap, matrix, paint);// 繪製的圖片和以前的如出一轍 mImageAltered.setImageBitmap(bitmapAltered); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }