SearchView是android系統中內置的一個搜索框組件,能夠很方便在添加在用戶界面之上,可是也帶來了一些問題,那就是searchview的UI是固定的,定製起來會很麻煩,若是對SearchView的要求比較高,徹底能夠採用button和EditText本身實現。android
<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:orientation="vertical" tools:context=".Main" > <SearchView android:id="@+id/sv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:imeOptions="actionGo" /> </LinearLayout>
在顯示suggestion的時候會用到下面的佈局文件:mytextview.xmlsql
<?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="50sp" android:orientation="vertical" > <TextView android:id="@+id/textview" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_vertical" android:paddingLeft="5sp" android:textSize="18sp" /> </LinearLayout>
activity代碼app
public class Main extends Activity { SearchView sv = null; ListView lv = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); sv = (SearchView) this.findViewById(R.id.sv); sv.setIconifiedByDefault(false); sv.setSubmitButtonEnabled(true); sv.setQueryHint("查詢"); //經過反射,修改默認的樣式,能夠從android的search_view.xml中找到須要的組件 try { Field field = sv.getClass().getDeclaredField("mSubmitButton"); field.setAccessible(true); ImageView iv = (ImageView) field.get(sv); iv.setImageDrawable(this.getResources().getDrawable( R.drawable.pointer)); } catch (Exception e) { e.printStackTrace(); } Cursor cursor = this.getTestCursor(); @SuppressWarnings("deprecation") SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.mytextview, cursor, new String[] { "tb_name" }, new int[] { R.id.textview }); sv.setSuggestionsAdapter(adapter); sv.setOnQueryTextListener(new OnQueryTextListener() { @Override public boolean onQueryTextChange(String str) { return false; } @Override public boolean onQueryTextSubmit(String str) { Toast.makeText(Main.this, str, Toast.LENGTH_SHORT).show(); return false; } }); } //添加suggestion須要的數據 public Cursor getTestCursor() { SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase( this.getFilesDir() + "/my.db3", null); Cursor cursor = null; try { String insertSql = "insert into tb_test values (null,?,?)"; db.execSQL(insertSql, new Object[] { "aa", 1 }); db.execSQL(insertSql, new Object[] { "ab", 2 }); db.execSQL(insertSql, new Object[] { "ac", 3 }); db.execSQL(insertSql, new Object[] { "ad", 4 }); db.execSQL(insertSql, new Object[] { "ae", 5 }); String querySql = "select * from tb_test"; cursor = db.rawQuery(querySql, null); } catch (Exception e) { String sql = "create table tb_test (_id integer primary key autoincrement,tb_name varchar(20),tb_age integer)"; db.execSQL(sql); String insertSql = "insert into tb_test values (null,?,?)"; db.execSQL(insertSql, new Object[] { "aa", 1 }); db.execSQL(insertSql, new Object[] { "ab", 2 }); db.execSQL(insertSql, new Object[] { "ac", 3 }); db.execSQL(insertSql, new Object[] { "ad", 4 }); db.execSQL(insertSql, new Object[] { "ae", 5 }); String querySql = "select * from tb_test"; cursor = db.rawQuery(querySql, null); } return cursor; } }
1.LayoutTransitionide
在3.0及之後只須要在XML中設置animateLayoutChanges="true"或者在Java代碼中添加一個LayoutTransition對象便可實現任何ViewGroup佈局改變時的動畫。佈局
目前系統中支持如下5種狀態變化,應用程序能夠爲下面任意一種狀態設置自定義動畫:動畫
一、APPEARING:容器中出現一個視圖。this
二、DISAPPEARING:容器中消失一個視圖。spa
三、CHANGING:佈局改變致使某個視圖隨之改變,例如調整大小,但不包括添加或者移除視圖。code
四、CHANGE_APPEARING:其餘視圖的出現致使某個視圖改變。xml
五、CHANGE_DISAPPEARING:其餘視圖的消失致使某個視圖改變。
注意在容器中設置了屬性android:animateLayoutChanges="true",這個時候容器佈局改變就已經有動畫效果了,只不過是系統默認的,好比添加一個按鈕會出現漸入動畫,移除一個按鈕會出現漸出動畫,而周圍的視圖則會平滑地填充移除時的空隙。
<?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" > <Button android:id="@+id/main_btn" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="添加控件"/> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:animateLayoutChanges="true" android:id="@+id/main_container" android:orientation="vertical"/> </LinearLayout>
可是若是咱們想自定義這些效果怎麼辦呢?使用LayoutTransition
package com.example.animtest; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.Keyframe; import android.animation.LayoutTransition; import android.animation.ObjectAnimator; import android.animation.PropertyValuesHolder; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.LinearLayout; public class AnimateLayoutTransition extends Activity { private LinearLayout ll; private LayoutTransition mTransition = new LayoutTransition(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.animate_layout_transition); ll = (LinearLayout) findViewById(R.id.ll); setupCustomAnimations(); ll.setLayoutTransition(mTransition); } public void add(View view) { final Button button = new Button(this); ll.addView(button); button.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { ll.removeView(button); } }); } // 生成自定義動畫 private void setupCustomAnimations() { // 動畫 - 開始添加view動畫 // Changing while Adding PropertyValuesHolder pvhLeft = PropertyValuesHolder.ofInt("left", 0, 1); PropertyValuesHolder pvhTop = PropertyValuesHolder.ofInt("top", 0, 1); PropertyValuesHolder pvhRight = PropertyValuesHolder.ofInt("right", 0, 1); PropertyValuesHolder pvhBottom = PropertyValuesHolder.ofInt("bottom", 0, 1); PropertyValuesHolder pvhScaleX = PropertyValuesHolder.ofFloat("scaleX", 1f, 0f, 1f); PropertyValuesHolder pvhScaleY = PropertyValuesHolder.ofFloat("scaleY", 1f, 0f, 1f); final ObjectAnimator changeIn = ObjectAnimator.ofPropertyValuesHolder( this, pvhLeft, pvhTop, pvhRight, pvhBottom, pvhScaleX, pvhScaleY).setDuration( mTransition.getDuration(LayoutTransition.CHANGE_APPEARING)); mTransition.setAnimator(LayoutTransition.CHANGE_APPEARING, changeIn); changeIn.addListener(new AnimatorListenerAdapter() { public void onAnimationEnd(Animator anim) { View view = (View) ((ObjectAnimator) anim).getTarget(); // View也支持此種動畫執行方式了 view.setScaleX(1f); view.setScaleY(1f); } }); // 動畫 - 開始移除動畫 // Changing while Removing Keyframe kf0 = Keyframe.ofFloat(0f, 0f); Keyframe kf1 = Keyframe.ofFloat(.9999f, 360f); Keyframe kf2 = Keyframe.ofFloat(1f, 0f); PropertyValuesHolder pvhRotation = PropertyValuesHolder.ofKeyframe( "rotation", kf0, kf1, kf2); final ObjectAnimator changeOut = ObjectAnimator .ofPropertyValuesHolder(this, pvhLeft, pvhTop, pvhRight, pvhBottom, pvhRotation) .setDuration( mTransition .getDuration(LayoutTransition.CHANGE_DISAPPEARING)); mTransition .setAnimator(LayoutTransition.CHANGE_DISAPPEARING, changeOut); changeOut.addListener(new AnimatorListenerAdapter() { public void onAnimationEnd(Animator anim) { View view = (View) ((ObjectAnimator) anim).getTarget(); view.setRotation(0f); } }); // 動畫 - 添加View動畫 // Adding ObjectAnimator animIn = ObjectAnimator.ofFloat(null, "rotationY", 90f, 0f).setDuration( mTransition.getDuration(LayoutTransition.APPEARING)); mTransition.setAnimator(LayoutTransition.APPEARING, animIn); animIn.addListener(new AnimatorListenerAdapter() { public void onAnimationEnd(Animator anim) { View view = (View) ((ObjectAnimator) anim).getTarget(); view.setRotationY(0f); } }); // 動畫 - 移除時View動畫 // Removing ObjectAnimator animOut = ObjectAnimator.ofFloat(null, "rotationX", 0f, 90f).setDuration( mTransition.getDuration(LayoutTransition.DISAPPEARING)); mTransition.setAnimator(LayoutTransition.DISAPPEARING, animOut); animOut.addListener(new AnimatorListenerAdapter() { public void onAnimationEnd(Animator anim) { View view = (View) ((ObjectAnimator) anim).getTarget(); view.setRotationX(0f); } }); } }