使用 Bundle 在 Activity 之间交换数据

使用 Bundle 在 Activity 之间交换数据

场景

当一个 Activity 启动另一个 Activity 时,常常会有一些数据需要传过去。因为两个 Activity 之间本来就有一个 Intent,因此我们主要将需要交换的数据放入 Intent 中即可。

简介

Intent 提供了多个重载的方法来“携带”额外的数据。

  1. putExtras(Bundle data):向 Intent 中放下需要“携带”的数据包。
  2. Bundle getExtras():取出 Intent 中所“携带”的数据包。
  3. putExtra(String key, Xxx value):向 Intent 中按 key-value 对的形式存入数据。
  4. getXxxExtra(String key):从 Intent 中按 key 取出指定类型的数据。

类型讲解

上面方法中的 Bundle 就是一个简单地数据携带包,该 Bundle 对象包含了多个方法来存入数据。

  1. putXxx(String key, Xxx value):向 Bundle 中放入 Int、Long 等各种类型的数据。
  2. putSerializable(String key, Serializable value):向 Bundle 中放入一个可序列化的对象。
  3. putParcelable(String key, Parcelable value):向 Bundle 中放入一个可序列化的对象。

bundle提取数据

为了取出 Bundle 数据携带包的数据,Bundle 提供了如下方法。

  1. getXxx(String key):从 Bundle 中取出 Int、Long 等各种类型的数据。
  2. getSerializable(String key):从 Bundel 中取出一个可序列化的对象。
  3. getParcelable(String key):从 Bundel 中取出一个可序列化的对象。
    从上面的介绍不难看出,Intent 主要通过 Bundle 对象来携带数据,因此 Intent 提供了 putExtras()和 getExtras()两个方法。除此之外,Intent 也提供了多个重载的 putExtra(String key,Xxx value)、getXxxExtra(String key)。其实 Intent 提供的 putExtra(String key,Xxx value)、getXxxExtra(String key)方法,只是两个便捷的方法,这些方法依然是存取 Intent 所携带的 Bundle 中的数据。

提示点

值得注意的是:
Intent 的 putExtra(String key, XXxx value)方法是“智能”的,当程序调用 Intent 的 putExtra(String key,Xxx value)方法向 Intent 中存入数据时,如果该 Intent 中已经携带了 Bundle 对象,则该方法直接向 Intent 所携带的 Bundle 中存入数据;如果 Intent 还没有携带 Bundle 对象,putExtra(String key,Xxx value)方法会优先为 Intent 创建一个 Bundle,再向 Bundle 中存入数据。
实例:用第二个 Activity 处理注册信息

<?xml version="1.0" encoding="utf-8"?><TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"

    android:layout_height="match_parent">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="请输入您的注册信息"
        android:textSize="20sp"/>
    <TableRow>

        <TextView
            android:layout_width="match_parent"

            android:layout_height="wrap_content"

            android:text="用户名:"

            android:textSize="16sp"/>

        <!-- 定义一个EditText,用于收集用户的账号 -->

        <EditText

            android:id="@+id/name"

            android:layout_width="match_parent"

            android:layout_height="wrap_content"

            android:hint="请填写想注册的账号"

            android:selectAllOnFocus="true"/>

    </TableRow>

    <TableRow>

        <TextView

            android:layout_width="match_parent"

            android:layout_height="wrap_content"

            android:text="密码:"

            android:textSize="16sp"/>

        <!-- 用于收集用户的密码 -->

        <EditText

            android:id="@+id/passwd"

            android:layout_width="match_parent"

            android:layout_height="wrap_content"

            android:password="true"

            android:selectAllOnFocus="true"/>

    </TableRow>

    <TableRow>

        <TextView

            android:layout_width="match_parent"

            android:layout_height="wrap_content"

            android:text="性别:"

            android:textSize="16sp"/>

        <!-- 定义一组单选框,用于收集用户注册的性别 -->

        <RadioGroup

            android:layout_width="match_parent"

            android:layout_height="wrap_content"

            android:orientation="horizontal">

            <RadioButton

                android:id="@+id/male"

                android:layout_width="wrap_content"

                android:layout_height="wrap_content"

                android:text="男"

                android:textSize="16sp"/>

            <RadioButton

                android:id="@+id/female"

                android:layout_width="wrap_content"

                android:layout_height="wrap_content"

                android:text="女"

                android:textSize="16sp"/>

        </RadioGroup>

    </TableRow>

    <Button

        android:id="@+id/bn"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:text="注册"
        android:textSize="16sp"/>
      </TableLayout>
public class MainActivity extends Activity {
    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);

        Button bn = (Button) findViewById(R.id.bn);

        bn.setOnClickListener(new OnClickListener() {

            public void onClick(View v) {

                EditText name = (EditText) findViewById(R.id.name);

                EditText passwd = (EditText) findViewById(R.id.passwd);

                RadioButton male = (RadioButton) findViewById(R.id.male);

                String gender = male.isChecked() ? "男 " : "女";

                Person p = new Person(name.getText().toString(), passwd

                        .getText().toString(), gender);

                // 创建一个Bundle对象

                Bundle data = new Bundle();

                data.putSerializable("person", p);

                // 创建一个Intent

                Intent intent = new Intent(MainActivity.this,

                        ResultActivity.class);

                intent.putExtras(data);

                // 启动intent对应的Activity

                startActivity(intent);

            }

        });

    }
}

下面是 ResultActivity 的界面布局文件。

<?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,用于显示用户输入的数据 -->
    <TextView
        android:id="@+id/name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="18sp"/>
    <TextView
        android:id="@+id/passwd"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="18sp"/>
    <TextView
        android:id="@+id/gender"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="18sp"/>
</LinearLayout>
public class ResultActivity extends Activity {

    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.result);

        TextView name = (TextView) findViewById(R.id.name);

        TextView passwd = (TextView) findViewById(R.id.passwd);

        TextView gender = (TextView) findViewById(R.id.gender);

        // 获取启动该Activity的Intent

        Intent intent = getIntent();

        // 直接通过Intent取出它所携带的Bundle数据包中的数据

        Person p = (Person) intent.getSerializableExtra("person");

        name.setText("您的用户名为:" + p.getName());

        passwd.setText("您的密码为:" + p.getPasswd());

        gender.setText("您的性别为:" + p.getGender());

    }
}
public class Person implements Serializable {
    private Integer id;

    private String name;

    private String passwd;

    private String gender;

    public Person(String name, String passwd, String gender) {

        this.name = name;

        this.passwd = passwd;

        this.gender = gender;

    }

    public Integer getId() {

        return id;

    }

    public void setId(Integer id) {

        this.id = id;

    }

    public String getName() {

        return name;

    }

    public void setName(String name) {

        this.name = name;

    }

    public String getPasswd() {

        return passwd;

    }

    public void setPasswd(String passwd) {

        this.passwd = passwd;

    }

    public String getGender() {

        return gender;

    }

    public void setGender(String gender) {

        this.gender = gender;

    }
}

启动其他 Activity 并返回结果

Activity 还提供了一个 startActivityForResult(Intent intent,int requestCode)方法来启动其他 Activity。该方法用于启动指定 Activity,而且期望获取指定 Activity 返回的结果。

为了获取被启动的 Activity 所返回的结果,需要从两个方面着手。

  1. 当前 Activity 需要重写 onActivityResult(int requestCode, int resultCode, Intent intent),当被启动的 Activity 返回结果时,该方法将会被触发,其中 requestCode 代表请求码,而 resultCode 代表 Activity 返回的结果码,这个结果码也是由开发者根据业务自行设定的。
  2. 被启动的 Activity 需要调用 setResult()方法设置处理结果。

实例:用第二个 Activity 让用户选择信息

public class MainActivity extends Activity {
    Button bn;
    EditText city;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        // 获取界面上的组件
        bn = (Button) findViewById(R.id.bn);
        city = (EditText) findViewById(R.id.city);
        // 为按钮绑定事件监听器
        bn.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View source) {
                // 创建需要对应于目标Activity的Intent
                Intent intent = new Intent(MainActivity.this,
                        SelectCityActivity.class);
                // 启动指定Activity并等待返回的结果,其中0是请求码,用于标识该请求
                startActivityForResult(intent, 0);
            }
        });
    }

    // 重写该方法,该方法以回调的方式来获取指定Activity返回的结果
    @Override
    public void onActivityResult(int requestCode
            , int resultCode, Intent intent) {
        // 当requestCode、resultCode同时为0时,也就是处理特定的结果
        if (requestCode == 0 && resultCode == 0) {
            // 取出Intent里的Extras数据
            Bundle data = intent.getExtras();
            // 取出Bundle中的数据
            String resultCity = data.getString("city");
            // 修改city文本框的内容
            city.setText(resultCity);
        }
    }
}

为了让当前 Activity 获取 SelectCityActivity 所返回的结果,开发者应该重写 onActivityResult()方法—-当被启动的 SelectCityActivity 返回结果时,onActivityResult()方法将会被调用。

因此还需要为上面 ActivityForResult 添加如下方法。

// 重写该方法,该方法以回调的方式来获取指定Activity返回的结果
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent intent) {
        // 当requestCode、resultCode同时为0时,也就是处理特定的结果
        if (requestCode == 0 && resultCode == 0) {
            // 取出Intent里的Extras数据
            Bundle data = intent.getExtras();
            // 取出Bundle中的数据
            String resultCity = data.getString("city");
            // 修改city文本框的内容
            city.setText(resultCity);
        }
    }
public class SelectCityActivity extends ExpandableListActivity {
    // 定义省份数组
    private String[] provinces = new String[]
            {"广东", "广西", "湖南"};
    private String[][] cities = new String[][]
            {
                    {"广州", "深圳", "珠海", "中山"},
                    {"桂林", "柳州", "南宁", "北海"},
                    {"长沙", "岳阳", "衡阳", "株洲"}
            };

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ExpandableListAdapter adapter = new BaseExpandableListAdapter() {
            // 获取指定组位置、指定子列表项处的子列表项数据
            @Override
            public Object getChild(int groupPosition, int childPosition) {
                return cities[groupPosition][childPosition];
            }

            @Override
            public long getChildId(int groupPosition, int childPosition) {
                return childPosition;
            }

            @Override
            public int getChildrenCount(int groupPosition) {
                return cities[groupPosition].length;
            }

            private TextView getTextView() {
                AbsListView.LayoutParams lp = new AbsListView.LayoutParams(
                        ViewGroup.LayoutParams.MATCH_PARENT, 64);
                TextView textView = new TextView(SelectCityActivity.this);
                textView.setLayoutParams(lp);
                textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
                textView.setPadding(36, 0, 0, 0);
                textView.setTextSize(20);
                return textView;
            }

            // 该方法决定每个子选项的外观
            @Override
            public View getChildView(int groupPosition, int childPosition,
                                     boolean isLastChild, View convertView, ViewGroup parent) {
                TextView textView = getTextView();
                textView.setText(getChild(groupPosition, childPosition)
                        .toString());
                return textView;
            }

            // 获取指定组位置处的组数据
            @Override
            public Object getGroup(int groupPosition) {
                return provinces[groupPosition];
            }

            @Override
            public int getGroupCount() {
                return provinces.length;
            }

            @Override
            public long getGroupId(int groupPosition) {
                return groupPosition;
            }

            // 该方法决定每个组选项的外观
            @Override
            public View getGroupView(int groupPosition, boolean isExpanded,
                                     View convertView, ViewGroup parent) {
                LinearLayout ll = new LinearLayout(SelectCityActivity.this);
                ll.setOrientation(LinearLayout.HORIZONTAL);
                ImageView logo = new ImageView(SelectCityActivity.this);
                ll.addView(logo);
                TextView textView = getTextView();
                textView.setText(getGroup(groupPosition).toString());
                ll.addView(textView);
                return ll;
            }

            @Override
            public boolean isChildSelectable(int groupPosition,
                                             int childPosition) {
                return true;
            }

            @Override
            public boolean hasStableIds() {
                return true;
            }
        };
        // 设置该窗口显示列表
        setListAdapter(adapter);
        getExpandableListView().setOnChildClickListener(
                new OnChildClickListener() {
                    @Override
                    public boolean onChildClick(ExpandableListView parent,
                                                View source, int groupPosition, int childPosition,
                                                long id) {
                        // 获取启动该Activity之前的Activity对应的Intent
                        Intent intent = getIntent();
                        intent.putExtra("city",
                                cities[groupPosition][childPosition]);
                        // 设置该SelectCityActivity的结果码,并设置结束之后退回的Activity
                        SelectCityActivity.this.setResult(0, intent);
                        // 结束SelectCityActivity。
                        SelectCityActivity.this.finish();
                        return false;
                    }
                });
    }
}
posted @ 2017-10-17 08:54  Dyleaf  阅读(421)  评论(0编辑  收藏  举报