Android零基础入门(五):UI常用组件

目录

 

第一节:Android布局之相对布局

第二节:AndroidStudio使用指南

第三节:Android布局之约束布局

第四节:Android菜单创建与使用

选项菜单(OptionMenu)

创建

加载

设置

上下文菜单(ContextMenu)

弹出菜单(PopupMenu)

动态创建菜单

经验分享

第五节:Android对话框处理

第六节:Activity生命周期详解

Activity的生命周期

Activity Lifecycle

Activity之间的数据传递

MainActivity向SecondActivity传递数据的三种方法:

SecondActivity向MainActivity回传数据:

第七节:Fragment创建及使用

一、Fragment介绍

Fragment VS Activity

生命周期

Lifecycle

二、Fragment的加载

静态加载

动态加载

三、Fragment传值

Activity向Fragment传值

Fragment向Activity传值


第一节:Android布局之相对布局

为什么要使用相对布局?
线性布局

  • 层级结构繁杂
  • 多嵌套
  • 不够灵活

相对布局

  • 灵活
  • 减少控件之间层级关系
  • 提高界面编程效率

相对布局属性-方向位置
• android:layout_below
• android:layout_above
• android:layout_toLeftOf
• android:layout_toRightOf

相对布局属性-方向对齐
• android:layout_alignTop
• android:layout_alignLeft
• android:layout_alignBottom
• android:layout_alignRight

相对布局属性-基准线对齐
• android:layout_alignBaseline

相对布局属性-父控件边缘对齐
• android:layout_alignParentLeft
• android:layout_alignParentRight
• android:layout_alignParentTop
• android:layout_alignParentBottom

相对布局属性-父控件中央对齐
• android:layout_centerInParent
• android:layout_centerVertical
• android:layout_centerHorizontal

相对布局新属性-头部/尾部对齐(4.2)
• android:layout_alignStart
• android:layout_alignEnd
• android:layout_alignParentStart
• android:layout_alignParentEnd

通用属性
• android:padding
• android:layout_margin
• android:layout_gravity
• android:gravity

第二节:AndroidStudio使用指南

一、AndroidStudio下载与安装

下载地址:http://www.androiddevtools.cn/

二、AndroidStudio常用设置

改变字体大小:

File->Settings->Editor-Font

变量前缀:

File->Settings->Editor->Code Style->Java->Code Generation

三、AndroidStudio常用快捷键

撤销:Ctrl+z

反撤销:Ctrl+shift+z

代码提示:Ctrl+Alt+space

格式化代码:Ctrl+Alt+L

代码自动修正:Alt+Enter

显示文档说明:Ctrl+Q

查找:Ctrl+f

全局查找:Ctrl+Shift+f

快捷生成结构体:Ctrl+Alt+T

清除无效包引用:Alt + Ctrl + O

注释代码(//):Ctrl + /

注释代码(/**/):Ctrl + Alt + /

上下移动代码:Alt + Shift +

移动内部类:F6

查看类的继承关系:Ctrl+H

四、常见问题--中文乱码

  1. File->Settings->Editor->File Encodings  相关设置改为:UTF-8或GBK
  2. Java文件->右键->File Encoding
  3. 修改buid.gradle文件,在android{ }内加入 compileOptions{ encoding "GBK(或UTF-8)"}

第三节:Android布局之约束布局

常用布局:

LinearLayout线性布局重要属性:

  • android:orientation(方向)
  • android:layout_weight(权重)

RelativeLayout相对布局依靠参照物定位的布局,最灵活的布局。重要属性:

  • android:layout_alignParentRight
  • android:layout_centerHorizontal
  • android:layout_toLeftOf
  • android:layout_alignRight

FrameLayout帧布局重要属性:

  • android:layout_gravity(控件重力)
  • android:foreground(前景)
  • android:foregroundGravity(前景重力)

TableLayout表格布局重要属性:

  • android:stretchColumns(可以拉伸的列,参数列号,如"0","0,1","*")
  • android:shrinkColumns(可以收缩的列,参数同上)
  • android:collapseColumns(可以隐藏的列)
  • //如果直接在TableLayout中添加控件,那么控件将和父容器等宽
  • //如果想让控件出现在同一行,那么这些控件的外层一定要加一对<TableRow>标签
  • //<TableRow>中控件的宽度都是默认wrap_content

GridLayout网格布局重要属性:

  • android:rowCount(行数量)
  • android:columnCount (列数量)
  • android:layout_row (位于第几行)
  • android:layout_rowSpan(跨几行)//需要搭配android:layout_gravity="fill"属性使用

参考:https://blog.csdn.net/weixin_39251617/article/details/79711668

ConstraintLayout约束布局重要属性:

  • app:layout_constraintBottom_toBottomOf (约束当前view的底部位置,值为控件ID或parent,Bottom可以替换为Top、Left、Right)
  • app:layout_constraintVirtical_bias="0.5"(水平偏移量,取值0~1,默认0.5,即居中)

Inspector操作区域认识:点击控件,在右侧自动出现操作区域

  • 调整水平、垂直偏移量
  • 设置margin属性
  • 调整控件宽高,属性值:Wrap_Content(包裹内容)、Fixed(固定值)、Match constraints(填充约束)

添加自动约束

  1. 点击菜单的Clear All Constraints 按钮
  2. 点击菜单Turn On Autoconnect 按钮
  3. 点击菜单Infer Constraints按钮

Guidelines基线 

1、菜单点击Guidelines,选择基线,点击布局,放置基线

2、点击基线顶端切换左对齐、右对齐、百分比模式

3、设置控件相对基线位置,如:左右对称等。

 

第四节:Android菜单创建与使用

在Android3.0,当用户按“菜单”按钮 时,选项菜单的内容会出现在屏幕底部, 可包含多达 6 个菜单项,超出部分则以“更多”来显示。

在Android3.0及更高版本的系统中, 选项菜单中的项目将出现在操作栏中, 用户通过操作栏右侧的操作或者点击设备菜单按钮来溢出菜单图标。

  • 选项菜单(OptionMenu)
  • 上下文菜单(ContextMenu)
  • 弹出菜单(PopupMenu)

选项菜单(OptionMenu)

选项菜单是一个应用的主菜单项,用于放置对应用产生全局影响的操作,如搜索/设置。

创建

  1. 创建菜单资源目录:res->new->Android Resource Directory->Resource Type(menu);
  2. 创建菜单文件:menu->new->Menu Resource File
  3. 添加菜单项:<menu><item/></menu>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <!--showAsAction属性值:always :直接在标题栏显示
    never:不显示
    withText:控制图标和文本一起显示
    ifRoom:有空间就显示-->
    <item android:title="保存"
        android:id="@+id/save"
        android:icon="@mipmap/ic_launcher"
        app:showAsAction="always"/>
    <item android:title="设置"
        android:id="@+id/setting"/>
    <item android:title="更多操作" >
        <menu >
            <item android:title="退出"
                android:id="@+id/exit"/>
            <item android:title="子菜单2" />
            <item android:title="子菜单3" />
        </menu>
    </item>
</menu>

加载

    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.option,menu);
        return true;
    }

设置

@Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()){
            case R.id.save:
                Toast.makeText(this,"保存",Toast.LENGTH_SHORT).show();
                break;
            case R.id.setting:
                Toast.makeText(this,"设置",Toast.LENGTH_SHORT).show();
                break;
            case R.id.exit:
                finish();
                break;
        }
        return true;
    }

上下文菜单(ContextMenu)

长按某个item不放,就会在屏幕中间弹出ContextMenu。

1.注册

registerForContextMenu(findViewById(R.id.ctx_btn));

2.创建 覆盖onCreateContextMenu

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
        getMenuInflater().inflate(R.menu.context,menu);
    }

3.菜单项的操作 覆盖onContextItemSelected

    @Override
    public boolean onContextItemSelected(MenuItem item) {
        switch (item.getItemId()){
            case R.id.delete:
                Toast.makeText(this,"删除",Toast.LENGTH_SHORT).show();
                break;
            case R.id.opera1:
                Toast.makeText(this,"操作1",Toast.LENGTH_SHORT).show();
                break;
            case R.id.opera2:
                Toast.makeText(this,"操作2",Toast.LENGTH_SHORT).show();
                break;
        }
        return super.onContextItemSelected(item);
    }

为按钮设置上下文操作模式

①实现ActionMode CallBack

    ActionMode.Callback cb = new ActionMode.Callback() {
        //创建,在启动上下文操作模式(startActionMode(Callback))时调用
        @Override
        public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
            Log.e("TAG","创建");
            getMenuInflater().inflate(R.menu.context,menu);
            return true;
        }

        //在创建方法后进行调用
        @Override
        public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) {
            Log.e("TAG","准备");
            return false;
        }

        @Override
        public boolean onActionItemClicked(ActionMode actionMode, MenuItem menuItem) {
            Log.e("TAG","点击");
            switch (menuItem.getItemId()){
                case R.id.delete:
                    Toast.makeText(MainActivity.this,"删除",Toast.LENGTH_SHORT).show();
                    break;
                case R.id.opera1:
                    Toast.makeText(MainActivity.this,"操作1",Toast.LENGTH_SHORT).show();
                    break;
                case R.id.opera2:
                    Toast.makeText(MainActivity.this,"操作2",Toast.LENGTH_SHORT).show();
                    break;
            }
            return true;
        }

②在view的长按事件中去启动上下文操作模式

    findViewById(R.id.ctx_btn).setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View view) {
                startActionMode(cb);
                return false;
            }
        });

 

弹出菜单(PopupMenu)

一个模态形式展示的弹出风格 的菜单,绑在某个View上, 一般出现在被绑定的View的下方。

        //popup_btn:演示PopupMenu
        final Button popupBtn = findViewById(R.id.popup_btn);
        popupBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //①实例化PopupMenu对象 (参数2:被锚定的view)
                final PopupMenu menu = new PopupMenu(MainActivity.this,popupBtn);
                //②加载菜单资源:利用MenuInflater将Menu资源加载到PopupMenu.getMenu()所返回的Menu对象中
                //将R.menu.xx对于的菜单资源加载到弹出式菜单中
                menu.getMenuInflater().inflate(R.menu.popup,menu.getMenu());
                //③为PopupMenu设置点击监听器
                menu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
                    @Override
                    public boolean onMenuItemClick(MenuItem menuItem) {
                        switch (menuItem.getItemId()){
                            case R.id.copy:
                                Toast.makeText(MainActivity.this,"复制",Toast.LENGTH_SHORT).show();
                                break;
                            case R.id.paste:
                                Toast.makeText(MainActivity.this,"粘贴",Toast.LENGTH_SHORT).show();
                                break;
                        }
                        return false;
                    }
                });
                //④千万不要忘记这一步,显示PopupMenu
                menu.show();
            }
        });

动态创建菜单
 

        //加载菜单资源
        //通过XML资源来设计menu
        //getMenuInflater().inflate(R.menu.option,menu);

        //纯java代码设计menu
        /*菜单结构
        ->设置
        ->更多
        ---->添加
        ---->删除
         */
        //参数1:组id     参数2:菜单项id    参数3:序号   参数4:文本
        menu.add(1, 1, 1,"设置");
        SubMenu sub = menu.addSubMenu(1,2,2,"更多");
        sub.add(2,3,1,"添加");
        sub.add(2,4,2,"删除");
        //一定要记得返回true,否则菜单不显示
        return true;

经验分享

xml定义Menu的优势

  •  清晰的菜单结构
  •  将菜单内容与应用的逻辑代码分离
  •  资源适配更容易

xml定义的Menu不显示

  •  onCreateOptionsMenu()方法必须返回true
  •  onOptionsItemSelected方法返回true
  •  调用父类的默认实现

第五节:Android对话框处理

一、普通对话框1

        //AlertDialog
        //AlertDialog的构造方法是被修饰为protected
        //因此包外是无法使用的,所以我们利用构建器
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        //设置对话框的标题
        builder.setTitle("提示");
        //设置内容
        builder.setMessage("你是否确定退出当前程序");
        //设置按钮
        builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
                //推出当前程序
                MainActivity.this.finish();
            }
        });
        builder.setNegativeButton("取消",null);
        //builder.setNeutralButton()
        //创建对话框,show方法内部已经包含create,所以不用调用create方法
        // builder.create();
        //对话框的展示方法
        builder.show();

二、普通对话框2

        AlertDialog dialog = new AlertDialog.Builder(this).create();
        dialog.setTitle("提示");
        dialog.setMessage("请为本次课堂打分");
        //5 3 1
        dialog.setButton(DialogInterface.BUTTON_POSITIVE, "5分", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
                Toast.makeText(MainActivity.this,"您选择了:5分",Toast.LENGTH_SHORT).show();
            }
        });
        dialog.setButton(DialogInterface.BUTTON_NEUTRAL, "3分", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {

            }
        });
        dialog.setButton(DialogInterface.BUTTON_NEGATIVE, "1分", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {

            }
        });
        //一定要调用show方法,否则对话框不展示
        dialog.show();

三、列表对话框

        final String[] items = {"我是1","我是2","我是3","我是4"};
        AlertDialog.Builder builer = new AlertDialog.Builder(this)
                .setTitle("请选择")
                //设置列表项
                .setItems(items, new DialogInterface.OnClickListener() {
                    //参数2:被点击项的索引
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        Toast.makeText(MainActivity.this,"您选择了:" + items[i],Toast.LENGTH_SHORT).show();
                    }
                });
        builer.show();

四、单选对话框

        final String[] stars = {"奥黛丽.赫本","安妮.海瑟薇","艾玛.沃森","桑德拉.布洛克"};
        AlertDialog.Builder builder = new AlertDialog.Builder(this)
                .setTitle("请选择你喜欢的明星")
                //参数1:选项
                //参数2:默认被选项,传某个选项的索引,传-1代表没有默认被选项
                //参数3:被选中时的事件
                .setSingleChoiceItems(stars, 0, new DialogInterface.OnClickListener() {
                    //单选按钮点击事件,不会关闭对话框
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        //Toast.makeText(MainActivity.this,"您最喜欢的明星是::" + stars[i],Toast.LENGTH_SHORT).show();
                        idx = i;//成员变量
                    }
                }).setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    //确定按钮点击事件,会关闭对话框
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        Toast.makeText(MainActivity.this,"您最喜欢的明星是::" + stars[idx],Toast.LENGTH_SHORT).show();
                    }
                });
        builder.show();

五、多选对话框

        final String[] sports = {"篮球","足球","乒乓球","网球","滑板","游泳"};
        final boolean[] checked = {true,false,true,true,false,false};
        AlertDialog.Builder builder = new AlertDialog.Builder(this)
                .setTitle("请选择你最喜欢的运动")
                //参数1:选项
                //参数2:默认备选项(true:选中,false:未选中)
                //参数3:被点击时会触发的事件
                .setMultiChoiceItems(sports, checked, new DialogInterface.OnMultiChoiceClickListener() {
                    //参数1:对话框本身
                    //参数2:按钮的索引
                    //参数3:标志按钮是否处于被选中true(选中)false(取消选中)
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i, boolean b) {
                        //无论是选中还是取消选中都会触发onclick方法
                        Log.e("Log",sports[i]);
                        //checked[i]=b; //系统默认已经实现这个功能,所以这行代码可以省略
                    }
                })
                .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        String msg = "您的爱好是:";
                        for(int j = 0 ; j < checked.length ; j++){
                            if(checked[j]){
                                msg += sports[j] + " ";
                            }
                        }
                        Toast.makeText(MainActivity.this,msg,Toast.LENGTH_SHORT).show();
                    }
                });
        builder.show();

六、等待对话框

        //进度对话框,默认样式就是转圈
        ProgressDialog dialog = new ProgressDialog(this);
        dialog.setTitle("我是一个等待对话框");
        dialog.setMessage("请等待...");
        dialog.setCancelable(false); //默认取值true,false:对话框无法关闭
        dialog.show();
        //dialog.dismiss(); //设置对话框消失,setCancelable(false)时使用

七、进度条对话框

        final ProgressDialog dialog = new ProgressDialog(this);
        dialog.setTitle("下载中...");
        dialog.setMessage("请等待");
        //设置进度条进度模糊(true:不显示进度的动态效果,false:精确显示进度)
        dialog.setIndeterminate(false);
        //设置对话框的样式为水平样式
        dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        dialog.show();
        //dialog.setProgress(40);
        new Thread(){
            @Override
            public void run() {
                super.run();
                //让进度条从1到100的运动
                for(int i = 1 ; i <= 100 ; i++){
                    dialog.setProgress(i);
                    try {
                        Thread.sleep(50);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                dialog.dismiss();
            }
        }.start();

八、输入对话框

        final EditText edt = new EditText(this);
        AlertDialog.Builder builder = new AlertDialog.Builder(this)
                .setTitle("提示")
                .setView(edt)
                .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        Toast.makeText(MainActivity.this , "您输入的是:" + edt.getText().toString() , Toast.LENGTH_SHORT).show();
                    }
                });
        builder.show();

九、自定义对话框

  1. 自定义一个类,继承于Dialog类,在构造方法中调用setContentView(R.layout.xx)来设定对话框的布局
  2. 设定自定义对话框的风格(不显示标题栏   不显示背景),调用含设定对话框风格参数的构造
  3. 对自定义对话框中的某些控件添加事件
  4. 实例化自定义的对话框,显示
public class MyDialog extends Dialog {

    //参数2:制定对话框的样式风格
    public MyDialog(@NonNull Context context, @StyleRes int themeResId) {
        super(context, themeResId);
        setContentView(R.layout.layout);

        Button yesBtn = (Button) findViewById(R.id.yes_btn);
        Button noBtn = (Button) findViewById(R.id.no_btn);

        noBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                dismiss();      //控制对话框消失
            }
        });
        yesBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                System.exit(0);
            }
        });
    }
}
<style name="mydialog" parent="android:style/Theme.Dialog">
    <item name="android:windowNoTitle">true</item>
    <item name="android:windowBackground">@android:color/transparent</item>
</style>
MyDialog dialog = new MyDialog(this,R.style.mydialog);
dialog.show();

布局文件layout

<?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="wrap_content"
    android:orientation="vertical"
    android:gravity="center_horizontal"
    android:background="@mipmap/dialog_bg">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="提示"
        android:textSize="34sp"
        android:textColor="#ffffff"
        android:textStyle="bold"
        android:layout_marginTop="30dp"
        />

    <View
        android:layout_width="fill_parent"
        android:layout_height="2dp"
        android:background="#ffffff"
        android:layout_marginTop="10dp"
        android:layout_marginBottom="10dp"
        />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="您确定要退出当前程序么"
        android:layout_marginTop="10dp"
        android:textColor="#ffffff"
        android:textSize="20sp"
        />

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_marginTop="15dp"
        android:layout_marginBottom="20dp"
        >
        <Button
            android:id="@+id/no_btn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="否"
            android:background="@mipmap/yes_or_no"
            android:textColor="#49bdca"
            />
        <Button
            android:id="@+id/yes_btn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="是"
            android:background="@mipmap/yes_or_no"
            android:textColor="#49bdca"
            android:layout_marginLeft="15dp"
            />
    </LinearLayout>
</LinearLayout>

十、对话框中应用ArrayAdapter

        final String[] items = {"Java","Mysql","Android","HTML","C","JavaScript"};
        //数组适配器
        //参数1:环境
        //参数2:布局资源索引,指的是每一项数据所呈现的样式android.R.layout.xxx
        //参数3:数据源
        //ArrayAdapter adapter = new ArrayAdapter(this,android.R.layout.simple_dropdown_item_1line,items);

        //参数3:int textviewId. 指定文本需要放在布局中对应id文本控制的位置
        ArrayAdapter adapter = new ArrayAdapter(this,R.layout.array_item_layout,R.id.item_txt,items);
        AlertDialog.Builder builer = new AlertDialog.Builder(this)
                .setTitle("请选择")
                //参数1:适配器对象(对数据显示样式的规则制定器)
                //参数2:监听器
                .setAdapter(adapter, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        Toast.makeText(MainActivity.this,items[i],Toast.LENGTH_SHORT).show();
                        dialogInterface.dismiss();
                    }
                });
        builer.show();

布局文件array_item_layout

<?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="wrap_content"
    android:orientation="horizontal"
    android:padding="10dp"
    android:gravity="center_vertical">

    <ImageView
        android:id="@+id/item_icon"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:src="@mipmap/star"/>

    <TextView
        android:id="@+id/item_txt"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="测试"
        android:layout_marginLeft="15dp"/>
</LinearLayout>

第六节:Activity生命周期详解

Activity的生命周期

onCreate(),onStart(),onResume(),onPause(),onStop(),onDestory(),onRestart()

 

以下是Google官方解释:

Activity Lifecycle

Activities in the system are managed as an activity stack. When a new activity is started, it is placed on the top of the stack and becomes the running activity -- the previous activity always remains below it in the stack, and will not come to the foreground again until the new activity exits.

An activity has essentially four states:

  • If an activity in the foreground of the screen (at the top of the stack), it is active or running.
  • If an activity has lost focus but is still visible (that is, a new non-full-sized or transparent activity has focus on top of your activity), it is paused. A paused activity is completely alive (it maintains all state and member information and remains attached to the window manager), but can be killed by the system in extreme low memory situations.
  • If an activity is completely obscured by another activity, it is stopped. It still retains all state and member information, however, it is no longer visible to the user so its window is hidden and it will often be killed by the system when memory is needed elsewhere.
  • If an activity is paused or stopped, the system can drop the activity from memory by either asking it to finish, or simply killing its process. When it is displayed again to the user, it must be completely restarted and restored to its previous state.

The following diagram shows the important state paths of an Activity. The square rectangles represent callback methods you can implement to perform operations when the Activity moves between states. The colored ovals are major states the Activity can be in.

 

 

Activity之间的数据传递

MainActivity向SecondActivity传递数据的三种方法:

一、使用Intent的putExtra方法。

MainActivity: intent.putExtra("button_title","慕课网");

SecondActivity: getIntent().getStringExtra("button_title");//判断getIntent()!=null

二、使用Bundle传递。

MainActivity:

bundle.putString("button_title","慕课网");

intent.putExtra("bdl",bundle);

SecondActivity:

bundle=getIntent().getBundleExtra("bdl");//判断getIntent()!=null

String str=bundle.getString("button_title");//判断bundle!=null

三、直接putExtra序列化对象。被传递对象需要实现Serializable或Parcelable接口。

Serializable:简单、内存高

Parcelable:推荐、麻烦

SecondActivity向MainActivity回传数据:

一、只通知不传数据。

MainActivity:startActivityForResult(intent,999);//请求代码

SecondActivity:在finish()之前,SetResult(RESULT_OK);

MainActivity:

onActivityResult(...)生命周期中

if(requestCode==999&&resultCode==RESULT_OK)

setTitle("SecondActivity关闭了");

二、关闭时回传数据。

SecondActivity:

intent.putExtra("imooc","慕课网");

setResult(RESULT_OK,intent);

MainActivity:

OnActivityResult(...data){

if(data!=null) data.getStringExtra("imooc");

第七节:Fragment创建及使用

一、Fragment介绍

为什么要使用Fragment?解决不同分辨率的终端适配问题。

Fragment VS Activity

  • Fragment Android 3.0之后才出现
  • 一个Activity可以运行多个Fragment
  • Fragment不能脱离Activity存在
  • Activity是屏幕的主体,Fragment是Activity的组成元素

生命周期

以下是Google官方解释:

Lifecycle

Though a Fragment's lifecycle is tied to its owning activity, it has its own wrinkle on the standard activity lifecycle. It includes basic activity lifecycle methods such as onResume(), but also important are methods related to interactions with the activity and UI generation.

The core series of lifecycle methods that are called to bring a fragment up to resumed state (interacting with the user) are:

  1. onAttach(Activity) called once the fragment is associated with its activity.
  2. onCreate(Bundle) called to do initial creation of the fragment.
  3. onCreateView(LayoutInflater, ViewGroup, Bundle) creates and returns the view hierarchy associated with the fragment.
  4. onActivityCreated(Bundle) tells the fragment that its activity has completed its own Activity.onCreate().
  5. onViewStateRestored(Bundle) tells the fragment that all of the saved state of its view hierarchy has been restored.
  6. onStart() makes the fragment visible to the user (based on its containing activity being started).
  7. onResume() makes the fragment interacting with the user (based on its containing activity being resumed).

As a fragment is no longer being used, it goes through a reverse series of callbacks:

  1. onPause() fragment is no longer interacting with the user either because its activity is being paused or a fragment operation is modifying it in the activity.
  2. onStop() fragment is no longer visible to the user either because its activity is being stopped or a fragment operation is modifying it in the activity.
  3. onDestroyView() allows the fragment to clean up resources associated with its View.
  4. onDestroy() called to do final cleanup of the fragment's state.
  5. onDetach() called immediately prior to the fragment no longer being associated with its activity.

二、Fragment的加载

静态加载

1、创建静态类继承自Fragment,重写onCreateView方法。

2、创建布局文件。

3、在onCreateView中加载.view=inflater.inflate(布局,容器,是否绑定跟布局);return view;

4、在Activity的布局文件中创建<fragment>标签 name属性指定为自建的Fragment类。(注也可以使用Class属性设置)

动态加载

1、在Activity的XML文件创建一个容器类型的控件,如:LinearLayout。

2、实例化一个Fragment类。

3、使用getFragmentMangager关联布局与Fragment对象。

    //Fragment    
    private MainFragment mainFragment=new MainFragment();
    private FindFragment findFragment=new FindFragment();
    private MeFragment meFragment=new MeFragment();

    //加载Fragment
    getSupportFragmentManager().beginTransaction()
                .add(R.id.container_main,mainFragment)
                .add(R.id.container_main,findFragment)
                .add(R.id.container_main,meFragment)
                .hide(findFragment)
                .hide(meFragment)
                .commit();

Fragment特点:模块化、可重用、可适配

 

三、Fragment传值

Activity向Fragment传值

一、使用setArgument传值

  1. 实例化Fragment时,通过setArgument,传入数据。
  2. 在onCreate中,调用getArgrument提取数据。
  3. 在onCreateView中使用数据。
        Fragment myFragment=new MyFragment();
        Bundle bundle=new Bundle();
        bundle.putString(HEHE,"我是哈哈");
        myFragment.setArguments(bundle);

上面的过程使用“静态工厂方法"更好,在MyFragment中添加下面代码:

    public static MyFragment newInstance(String title){
        MyFragment fragment=new MyFragment();
        Bundle bundle=new Bundle();
        bundle.putString(BUNDLE_TITLE,title);
        fragment.setArguments(bundle);
        return fragment;
    }
Fragment myFragment = MyFragment.newInstance("我是list");

二、通过onAttach获取activity实例,再通过activity实例传递数据。(废弃)

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        myActivity = activity;
    }

 

Fragment向Activity传值

一、通过接口传递数据

  1. 自定义接口,在Fragment中创建接口类型变量,并提供方法让Activity订阅。
  2. 在Activity中实例化Fragment并订阅接口。
  3. Fragment发出通知,Activity接收数据。

MyFragment代码:

    public interface OnTitleListener {
        public void onClick(String str);
    }
    private OnTitleListener mOnTitleListener;
    public void setOnTitleListener(OnTitleListener onTitleListener) {
        this.mOnTitleListener = onTitleListener;
    }


    mTextView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
        if(mOnTitleListener !=null){
           mOnTitleListener.onClick(mTitle);
           }
        }
    });

Activity代码:

        MyFragment list = MyFragment.newInstance("list");
        list.setOnTitleListener(new MyFragment.OnTitleListener() {
            @Override
            public void onClick(String str) {
                setTitle(str);
            }
        });

二、通过onAttach获取activity实例,再通过activity实例传递数据。(废弃)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值