安卓基础第十一天(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);
    }

}

猜你喜欢

转载自blog.csdn.net/opopopwqwqwq/article/details/79382090
今日推荐