安卓基礎第十一天(Fragment,AutoCompleteTextView,動畫,通知欄)

Fragment


Fragment(碎片)就是小型的Activity,它是在Android3.0 時出現的。

  • 可以把fragment 想象成activity的一個模塊化區域
  • 有它自己的生命週期,接收屬於它自己的輸入事件,並且可以在activity運行期間添加和刪除

Fargment入門


  • 爲Fragment 定義一個佈局
<?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" >

    <TextView
        android:id="@+id/tv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="我是Fragment1裏面的內容"
        android:textColor="#ff0000" />

</LinearLayout>
  • 定義類繼承Fragment
  • 重寫類中的onCreateView 方法,返回一個View 對象作爲當前Fragment 的根佈局。如果fragment 不提供UI,可以返回null
//定義Fragment 理解爲 是Activity的一部分
public class Fragment1 extends Fragment {

    //當系統第一次畫ui的時候調用   通過這個方法方法可以讓Fragment顯示自己的佈局內容
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        //通過打氣筒把一個佈局轉換成一個View對象
        View view = inflater.inflate(R.layout.fragment1, null); 
        return view;
    }   
}
  • 展示:一是使用佈局配置,二是代碼動態加載
    配置
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <fragment android:name="com.itheima.fragmendemo.Fragment1"
            android:id="@+id/list"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="match_parent" />
</LinearLayout>

動態加載

public class MainActivity extends Activity {
    @SuppressWarnings("deprecation")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //[1]獲取手機的分辨率 
        WindowManager wm  =  (WindowManager) getSystemService(WINDOW_SERVICE);
        int width = wm.getDefaultDisplay().getWidth();
        int height = wm.getDefaultDisplay().getHeight();
        //[2]判斷橫豎屏 

        //[3]獲取Fragment的管理者  通過上下文直接獲取
        FragmentManager fragmentManager = getFragmentManager();
        FragmentTransaction beginTransaction = fragmentManager.beginTransaction(); //開啓事物 

        if(height > width){
            //說明是豎屏    加載一個Fragment  android.R.id.content //代表當前手機的窗體
            beginTransaction.replace(android.R.id.content, new Fragment1());
        }else {
            //說明是橫屏  加載一個Fragment 
            beginTransaction.replace(android.R.id.content, new Fragment2());
        }
        //[4]最後一步 記得comment
        beginTransaction.commit();
    }
}

示例 使用Fragment模仿微信界面佈局


public class MainActivity extends Activity implements OnClickListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // [1]找到按鈕
        Button btn_wx = (Button) findViewById(R.id.btn_wx);
        Button btn_contact = (Button) findViewById(R.id.btn_contact);
        Button btn_disconver = (Button) findViewById(R.id.btn_disconver);
        Button btn_me = (Button) findViewById(R.id.btn_me);
        // [2]設置點擊事件
        btn_wx.setOnClickListener(this);
        btn_disconver.setOnClickListener(this);
        btn_me.setOnClickListener(this);
        btn_contact.setOnClickListener(this);

    }

    @Override
    public void onClick(View v) {

        //[4]獲取Fragment的管理者 
        FragmentManager fragmentManager = getFragmentManager();
        FragmentTransaction beginTransaction = fragmentManager.beginTransaction();

        // 具體判斷點擊的是哪個按鈕
        switch (v.getId()) {
        case R.id.btn_wx: // 點擊的是微信
            beginTransaction.replace(R.id.ll_layout, new WxFragment());
            break;
        case R.id.btn_contact: // 點擊的是聯繫人
            beginTransaction.replace(R.id.ll_layout, new ContactFragment());
            break;
        case R.id.btn_disconver: // 點擊的發現
            beginTransaction.replace(R.id.ll_layout, new DiscoverFragment());
            break;
        case R.id.btn_me: // 點擊的是我
            beginTransaction.replace(R.id.ll_layout, new MeFragment());
            break;
        }

        //記得comment 
        beginTransaction.commit();
    }
}

Fragment 的生命週期


onAttach:綁定到activity
onCreate:創建fragment
onCreateView: 創建fragment 的佈局
onActivityCreated: activity 創建完成後
onStart: 可見, 不可交互
onResume: 可見, 可交互
onPause: 部分可見, 不可交互
onStop:不可見
onDestroyView: 銷燬fragment 的view 對象
onDestroy: fragment 銷燬了
onDetach: 從activity 解綁了
聲明週期

  • Fragment 的向下兼容
    Fragment 是在Android 3.0 才推出的
    1. 把所有Fragment 和FragmentManager 改成support-v4 包下的類
    2. 把Activity 的繼承改爲FragmentActivity(support-v4 包下的)

Fragment 之間的通信案例


  • Fragment有一個公共的橋樑 Activity

    Fragment1

    //定義Fragment 理解爲 是Activity的一部分
    public class Fragment1 extends Fragment {
    
    //當系統第一次畫ui的時候調用   通過這個方法方法可以讓Fragment顯示自己的佈局內容
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
    
        //通過打氣筒把一個佈局轉換成一個View對象
        View view = inflater.inflate(R.layout.fragment1, null);
    
        //[1]找到按鈕 設置點擊事件 
        view.findViewById(R.id.btn_update).setOnClickListener(new OnClickListener() {
    
            @Override
            public void onClick(View v) {
                //[2]修改fragment2裏面的內容  通過fragment的公共橋樑 --->activity
                Fragment2 fragment2 =  (Fragment2) getActivity().getFragmentManager().findFragmentByTag("f2");
                fragment2.updateText("哈哈哈呵呵");
            }
        });
        return view;
    }   
    }

Fragment2

public class Fragment2 extends Fragment {

    private TextView tv_content;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment2, null);
        //[1]找到tv

        tv_content = (TextView) view.findViewById(R.id.tv_content);
        return view;
    }

    //修改textview的內容
    public void updateText(String content){
        tv_content.setText(content);
    }   
}

AutoCompleteTextView

示例

    <AutoCompleteTextView
        android:id="@+id/actv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:completionThreshold="1"
         />

代碼

public class MainActivity extends Activity {

    //模擬actv這個控件要顯示的數據
     private  String[] COUNTRIES = new String[] {
         "laofang", "laoli", "laozhang", "laobi", "laowang","aa","abb","ccc"
     };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //[1]找到控件
        AutoCompleteTextView actv = (AutoCompleteTextView) findViewById(R.id.actv);

        //[2]actv這個控件顯示數據的原理和listview一樣 需要一個數據適配器
         ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                 android.R.layout.simple_dropdown_item_1line, COUNTRIES);

         //[3]顯示數據 
         actv.setAdapter(adapter);
    }
}

動畫


Android 3.0 以前,Android 支持兩種動畫模式,tween animation,frame animation
在android3.0 中又引入了一個新的動畫系統:property animation

幀動畫Frame Animation

Frame Animation(幀動畫):創建一個Drawable 序列,這些Drawable 可以按照指定的時間間隔一個一個的顯示,也就是順序播放事先做好的圖像。

  • 將準備好的圖片文件放到res/drawable-hdpi 目錄中。
  • 在項目的res 目錄下創建文件夾drawable,然後在文件夾下面定義動畫XML 文件,文件名稱可以自定義,例如frame_anim.xml。
  • 打開創建好的xml 文件,在裏面添加根節點,
  • 可以在此根節點中設置屬性”android:oneshot”來控制動畫只播放一次,否則系統將默認持續播放。在根節點 下爲幀動畫的每幅圖片添加一個 節點, 節點的”android:drawable”屬性是圖片的資源id,”android:duration”屬性指定圖片展示的時間(一般每秒展示5-8 張圖片就可以感受到動畫的效果)。
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="true" >
    <item
        android:drawable="@drawable/a1"
        android:duration="200">
    </item>
    <item
        android:drawable="@drawable/a2"
        android:duration="200">
    </item>
</animation-list>
  • 在動畫start()之前要先stop(),不然在第一次動畫之後會停在最後一幀,這樣動畫就只會觸發一次。
  • 最後一點是SDK 中提到的, 不要在onCreate 中調用start , 因爲AnimationDrawable 還沒有完全跟Window 相關聯,如果想要界面顯示時就開始動畫的話,可以在onWindowFoucsChanged()中調用start()。

代碼

public class MainActivity extends Activity {
    private ImageView iv;
    private AnimationDrawable animationDrawable;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        iv = (ImageView) findViewById(R.id.iv);
        iv.setImageResource(R.drawable.frame_anim);
        animationDrawable = (AnimationDrawable) iv.getDrawable();
    }

    public void startAnimation(View view) {// 點擊按鈕調用此方法
        if (animationDrawable.isRunning())
            animationDrawable.stop();
        animationDrawable.start();
    }
}

補間(漸變)動畫 TweenAnimation


View Animation(Tween Animation):補間動畫,給出兩個關鍵幀,通過一些算法將給定屬性值在給定的時間內在兩個關鍵幀間漸變。

漸變包括:包括平移、縮放、旋轉、改變透明度

特性:
動畫效果不會改變控件真實的座標
只能應用於View 對象,而且只支持一部分屬性,如支持縮放旋轉而不支持背景顏色的改變。

  • 使用代碼實現補間動畫

常用的方法
Animation:
setDuration 設置動畫的執行時間
setRepeatCount 設置動畫的重複次數
setRepeatMode 指定重複的模式(如:反轉)
setFillAfter 指示動畫指定完畢之後控件的狀態是否停留在動畫停止的時候
setAnimationListener 設置動畫的事件監聽器
ImageView:
startAnimation(Animation a) 讓ImageView 執行某動畫

示例代碼

public class MainActivity extends Activity {

    private ImageView iv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 這個控件用來執行動畫
        iv = (ImageView) findViewById(R.id.iv);
        iv.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(getApplicationContext(), "你點不到我", 1).show();
            }
        });
    }

    // 點擊按鈕 實現透明效果
    public void click1(View v) {

        //創建透明動畫  1.0意味着完全不透明   0.0意外者完全透明 
        AlphaAnimation  aa = new AlphaAnimation(1.0f, 0.0f);
        aa.setDuration(2000); //設置動畫執行的時間
        aa.setRepeatCount(1); //設置動畫重複的次數 
        aa.setRepeatMode(Animation.REVERSE); //設置重複的模式
        //開始執行動畫 
        iv.startAnimation(aa);
    }

    // 點擊按鈕 實現旋轉效果
    public void click2(View v) {
        //fromDegrees 開始角度    toDegrees 結束的角度
//      RotateAnimation ra = new RotateAnimation(0, 360);
        RotateAnimation ra = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);

        ra.setDuration(2000); //設置動畫執行的時間
        ra.setRepeatCount(1); //設置動畫重複的次數 
        ra.setRepeatMode(Animation.REVERSE); //設置重複的模式
        //開始執行動畫 
        iv.startAnimation(ra);
    }

    // 點擊按鈕 實現縮放效果
    public void click3(View v) {
        ScaleAnimation sa = new ScaleAnimation(1.0f, 2.0f, 1.0f, 2.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); 
        sa.setDuration(2000); //設置動畫執行的時間
        sa.setRepeatCount(1); //設置動畫重複的次數 
        sa.setRepeatMode(Animation.REVERSE); //設置重複的模式
        //開始執行動畫 
        iv.startAnimation(sa);
    }

    // 點擊按鈕 實現平移效果
    public void click4(View v) {
        TranslateAnimation ta = new TranslateAnimation(Animation.RELATIVE_TO_PARENT, 0, Animation.RELATIVE_TO_PARENT, 0, Animation.RELATIVE_TO_PARENT, 0, Animation.RELATIVE_TO_PARENT, 0.2f);
        ta.setDuration(2000); //設置動畫執行的時間
        ta.setFillAfter(true);//當動畫結束後  停留在結束的位置上
        //開始執行動畫 
        iv.startAnimation(ta);
    }

    //點擊按鈕 讓動畫一起執行 
    public void click5(View v) {
        //創建動畫的合集
        AnimationSet set = new AnimationSet(true);
        AlphaAnimation  aa = new AlphaAnimation(1.0f, 0.0f);
        aa.setDuration(2000); //設置動畫執行的時間
        aa.setRepeatCount(1); //設置動畫重複的次數 
        aa.setRepeatMode(Animation.REVERSE); //設置重複的模式
RotateAnimation ra = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);   
        ra.setDuration(2000); //設置動畫執行的時間
        ra.setRepeatCount(1); //設置動畫重複的次數 
        ra.setRepeatMode(Animation.REVERSE); //設置重複的模式

        ScaleAnimation sa = new ScaleAnimation(1.0f, 2.0f, 1.0f, 2.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); 
        sa.setDuration(2000); //設置動畫執行的時間
        sa.setRepeatCount(1); //設置動畫重複的次數 
        sa.setRepeatMode(Animation.REVERSE); //設置重複的模式

        //添加動畫
        set.addAnimation(aa);
        set.addAnimation(ra);
        set.addAnimation(sa);   

        //執行動畫 
        iv.startAnimation(set);
    }   
}
  • 使用XML實現補間動畫

這裏寫圖片描述

如果使用xml方式定義補間動畫 要在res下創建一個anim目錄

alpha 透明度

<?xml version="1.0" encoding="utf-8"?>
<alpha  
    android:fromAlpha="1.0"
    android:toAlpha="0.0"
    android:duration="2000"
    android:repeatCount="1"
    android:repeatMode="reverse"
    xmlns:android="http://schemas.android.com/apk/res/android">
</alpha>

rotate 旋轉

<?xml version="1.0" encoding="utf-8"?>
<rotate   
    android:pivotX="50%"
    android:pivotY="50%"
    android:fromDegrees="0"
    android:toDegrees="360"
    android:repeatMode="reverse"
    android:repeatCount="1"
    android:duration="2000"
    xmlns:android="http://schemas.android.com/apk/res/android">
</rotate>

scale 縮放

<?xml version="1.0" encoding="utf-8"?>
<scale
    android:fromXScale="1.0"
    android:toXScale="2.0"
    android:fromYScale="1.0"
    android:toYScale="2.0"
    android:pivotX="50%"
    android:pivotY="50%"
    android:repeatCount="1"
    android:repeatMode="reverse"
    android:duration="2000"
    xmlns:android="http://schemas.android.com/apk/res/android">
</scale>

translate 位移

<?xml version="1.0" encoding="utf-8"?>
<translate
    android:fromXDelta="0%p"
    android:toXDelta="0%p"
    android:fromYDelta="0%p"
    android:toYDelta="20%p"
    android:fillAfter="true"   
    android:duration="2000"
    xmlns:android="http://schemas.android.com/apk/res/android">
</translate>

集合 set

<?xml version="1.0" encoding="utf-8"?>
<set>
<!-- 屬性略-->
    <alpha></alpha>
    <rotate></rotate>
    <translate></translate> 
    <scale> </scale>
</set>

調用

        Animation aa = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.alpha); 
        //開始執行動畫 
        iv.startAnimation(aa);

屬性動畫 Property Animation


屬性動畫會改變控件真實的座標
如果使用xml方式定義屬性動畫 要在res下創建一個animator目錄

代碼

public class MainActivity extends Activity {

    private ImageView iv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //加載佈局
        setContentView(R.layout.activity_main);

        //作用 執行動畫
        iv = (ImageView) findViewById(R.id.iv);
        //給iv設置了一個監聽事件 
        iv.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {

                Toast.makeText(MainActivity.this, "你點不到我", 0).show();
            }
        });

        //
//      iv.setTranslationX(translationX)
//      iv.setScaleX(scaleX)
//      iv.setAlpha(alpha)
//      iv.setro

    }

    //位移動畫
    public void translate(View v){
        //創建屬性動畫
        /**
         * target 執行的目標   誰執行動畫
         * propertyName 屬性名字  The name of the property being animated.
         * float... values 可變參數 
         */
        ObjectAnimator oa = ObjectAnimator.ofFloat(iv, "translationX", 10, 50,20,150);
        oa.setDuration(2000);
        oa.start(); //開始動畫

    }
    //縮放動畫
    public void scale(View v){

        ObjectAnimator oa = ObjectAnimator.ofFloat(iv, "scaleY", 0.1f, 2, 1, 2);
        oa.setDuration(2000);
        oa.start();
    }

    //實現透明的效果 
    public void alpha(View v){
        ObjectAnimator oa = ObjectAnimator.ofFloat(iv, "alpha", 0, 0.5f, 0, 1,0,1);
        oa.setDuration(2000);
        oa.start();
    }

    //實現旋轉的效果
    public void rotate(View v){
//      ObjectAnimator oa = ObjectAnimator.ofFloat(iv, "rotation", 0, 180, 90, 360);
        ObjectAnimator oa = ObjectAnimator.ofFloat(iv, "rotationY", 0, 180, 90, 360);
        oa.setDuration(2000);
        oa.start();
    }

    //一起飛 
    public void fly(View v){
        AnimatorSet as = new AnimatorSet();
        ObjectAnimator oa = ObjectAnimator.ofFloat(iv, "translationX", 10, 50, 20, 100);
        ObjectAnimator oa2 = ObjectAnimator.ofFloat(iv, "scaleY", 0.1f, 2, 1, 2);
        ObjectAnimator oa3 = ObjectAnimator.ofFloat(iv, "alpha", 0, 0.5f, 0, 1);
        ObjectAnimator oa4 = ObjectAnimator.ofFloat(iv, "rotationY", 0, 180, 90, 360);
        as.setDuration(2000);
        as.setTarget(iv);
        //往集合中添加動畫
        //挨個飛
        as.playSequentially(oa, oa2, oa3, oa4);
        //一起飛
//      as.playTogether(oa, oa2, oa3, oa4);
        as.start();
    }

    //使用xml的方式創建屬性動畫
    public void playxml(View v){
        ObjectAnimator oa = (ObjectAnimator) AnimatorInflater.loadAnimator(this, R.animator.oanimator);
        //設置執行目標
        oa.setTarget(iv);
        oa.start();//開始執行
    }
}

xml實現

<?xml version="1.0" encoding="utf-8"?>
<animator xmlns:android="http://schemas.android.com/apk/res/android" >
    <objectAnimator 
        android:propertyName="translationX"
        android:duration="2000"
        android:valueFrom="10"
        android:valueTo="100"></objectAnimator>
</animator>

通知欄


通知用於在狀態欄顯示消息,消息到來時以圖標方式表示,
如果需要查看消息,可以拖動狀態欄到屏幕下方即可查看消息,
在Android 中通過通知管理器NotificationManager 來發出或關閉一個通知。

  1. 若設置了彈出通知會有聲音/震動/亮燈的效果,注意添加對應權限,否則會拋錯比如,設置震動需加權限android.permission.VIBRATE
  2. 獲取延期意圖PendingIntent 時,封裝的意圖對象必須採用隱式的方式
  3. startForeground(id, notification);可以提升進程優先級
public class MainActivity extends Activity {

    private NotificationManager nm;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //[1]獲取NotificationManager 的實例 
         nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    }

    // 點擊按鈕發送一條通知
    public void click1(View v) {

        //鏈式調用
    /*  Notification noti = new Notification.Builder(this)
        .setContentTitle("我是大標題")
        .setContentText("我是標題的內容")
        .setSmallIcon(R.drawable.ic_launcher)
        .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher))
        .build();*/


        //兼容低版本的寫法   使用過時的方法 
        Notification notification = new  Notification(R.drawable.ic_launcher, "我接收到了一條通知", System.currentTimeMillis());
        //來一條通知 設置一下震動   讓呼吸燈亮 
        notification.defaults = Notification.DEFAULT_ALL;

        //設置通知不讓清除
        notification.flags = Notification.FLAG_NO_CLEAR;


        //創建意圖對象
        Intent intent = new Intent();
        //實現撥打電話的功能 
        intent.setAction(Intent.ACTION_CALL);
        intent.setData(Uri.parse("tel:"+119));
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 1, intent, Intent.FLAG_ACTIVITY_NEW_TASK);
        //點擊通知對應的業務邏輯
        notification.setLatestEventInfo(this, "小芳", "老地方見", pendingIntent);

        //發出通知
        nm.notify(10, notification);

    }

    // 點擊按鈕 取消發送一條通知
    public void click2(View v) {
        //取消通知
        nm.cancel(10);
    }

}
發佈了174 篇原創文章 · 獲贊 63 · 訪問量 35萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章