从 Fragment 创建 Intent 并将数据从 Intent 活动传回 Fragment(选项卡式应用程序)

Posted

技术标签:

【中文标题】从 Fragment 创建 Intent 并将数据从 Intent 活动传回 Fragment(选项卡式应用程序)【英文标题】:Creating an Intent from a Fragment and passing data back to that Fragment from the Intent activity (Tabbed App) 【发布时间】:2018-06-23 09:17:01 【问题描述】:

我有一点问题,我似乎无法通过搜索解决它。 我注意到还有其他解决方案,但是当我通过事务传递捆绑包时,程序停止工作,并且到目前为止所有其他解决方案都失败了。

请注意,这是一个选项卡式应用程序。

我正在尝试做什么。

    单击按钮打开一个新的 Intent 可扩展列表视图 在可展开列表视图的新 Intent 上选择项目 将可扩展列表活动中的数据传回片段

代码如下

MainActivity.java(这里没什么特别的)

    import android.support.design.widget.TabLayout;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;

import android.widget.TextView;

public class MainActivity extends AppCompatActivity 


    /**
     * The @link android.support.v4.view.PagerAdapter that will provide
     * fragments for each of the sections. We use a
     * @link FragmentPagerAdapter derivative, which will keep every
     * loaded fragment in memory. If this becomes too memory intensive, it
     * may be best to switch to a
     * @link android.support.v4.app.FragmentStatePagerAdapter.
     */
    private SectionsPagerAdapter mSectionsPagerAdapter;

    /**
     * The @link ViewPager that will host the section contents.
     */
    private ViewPager mViewPager;

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

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        // Create the adapter that will return a fragment for each of the three
        // primary sections of the activity.
        mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());

        // Set up the ViewPager with the sections adapter.
        mViewPager = (ViewPager) findViewById(R.id.container);
        mViewPager.setAdapter(mSectionsPagerAdapter);

        TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);

        mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
        tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager));



    


    @Override
    public boolean onCreateOptionsMenu(Menu menu) 
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    

    @Override
    public boolean onOptionsItemSelected(MenuItem item) 
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) 
            return true;
        

        return super.onOptionsItemSelected(item);
    

    /**
     * A placeholder fragment containing a simple view.
     */
    public static class PlaceholderFragment extends Fragment 
        /**
         * The fragment argument representing the section number for this
         * fragment.
         */
        private static final String ARG_SECTION_NUMBER = "section_number";

        public PlaceholderFragment() 
        

        /**
         * Returns a new instance of this fragment for the given section
         * number.
         */
        public static PlaceholderFragment newInstance(int sectionNumber) 
            PlaceholderFragment fragment = new PlaceholderFragment();
            Bundle args = new Bundle();
            args.putInt(ARG_SECTION_NUMBER, sectionNumber);
            fragment.setArguments(args);
            return fragment;
        

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) 
            View rootView = inflater.inflate(R.layout.fragment_main, container, false);
            TextView textView = (TextView) rootView.findViewById(R.id.section_label);
            textView.setText(getString(R.string.section_format, getArguments().getInt(ARG_SECTION_NUMBER)));
            return rootView;
        
    

    /**
     * A @link FragmentPagerAdapter that returns a fragment corresponding to
     * one of the sections/tabs/pages.
     */
    public class SectionsPagerAdapter extends FragmentPagerAdapter 

        public SectionsPagerAdapter(FragmentManager fm) 
            super(fm);
        

        @Override
        public Fragment getItem(int position) 
            // getItem is called to instantiate the fragment for the given page.
            // Return a PlaceholderFragment (defined as a static inner class below).
            switch (position) 
                case 0:
                    return MainActivity.PlaceholderFragment.newInstance(position + 1);
                case 1:
                    return exercises.newInstance();
                case 2:
                    return MainActivity.PlaceholderFragment.newInstance(position + 1);
                case 3:
                    return MainActivity.PlaceholderFragment.newInstance(position + 1);
                case 4:
                    return MainActivity.PlaceholderFragment.newInstance(position + 1);
                //case two for later
            /*case 2:
                return AnotherFragment.newInstance();*/
            
            return null;
        

        @Override
        public int getCount() 
            // Show 5 total pages.
            return 5;
        


    



exerciseList.Java(可扩展的listView类,不包含自定义适配器)

package com.example.rowan.assignment1;
/* Intent activity created for used to select exercise from expandable List menu to save space on other App pages
*/


import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.ExpandableListView;

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class exerciseList extends AppCompatActivity 
        ExpandableListAdapter listAdapter;
        ExpandableListView expListView;
        List<String> listDataHeader;
        HashMap<String, List<String>> listDataChild;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_exercise_list);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        //get the listView
        expListView = (ExpandableListView) findViewById(R.id.lvExp);
        //set the data
        prepareListData();
        listAdapter = new ExpandableListAdapter(this, listDataHeader, listDataChild);

        // setting list adapter
        expListView.setAdapter(listAdapter);

        expListView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() 
            @Override
            public boolean onChildClick(ExpandableListView parent, View v,
                                        int groupPosition, int childPosition, long id) 
                String muscle = listDataHeader.get(groupPosition);
                String exercise = listDataChild.get( listDataHeader.get(groupPosition)).get(
                        childPosition);
                //On ListView child click, return to fragment with data


                //Previous attempts
                /*Intent intent = new Intent(getApplicationContext(),
                        MainActivity.class);

                Bundle bundle = new Bundle();
                bundle.putString("muscle", muscle);
                bundle.putString("exercise", exercise);


                startActivity(intent);

                //another attempt
                Bundle args = new Bundle();
                args.putString("muscle", muscle);
                args.putString("exercise", exercise);
                exercises fragment = new exercises();
                fragment.setArguments(args);
                FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
                transaction.replace(R.id.tabItem2, fragment);
                transaction.commit();

                //yet another
                exercises fragment = (exercises) getSupportFragmentManager().findFragmentById(R.id.tabItem2);
                fragment.setData(muscle,exercise);
                finish();

                //4th attempt
                try 
                    FileOutputStream out;
                    store f = new store(muscle, exercise);
                    out=openFileOutput("exfile", MODE_PRIVATE);
                    ObjectOutputStream oout = new ObjectOutputStream(out);
                    oout.writeObject(f);
                    oout.close();
                
                catch (Exception ex) 
                    ex.printStackTrace();
                
                finish();
                */

                return false;
            
        );
    


private void prepareListData()
        listDataHeader = new ArrayList<String>();
        listDataChild = new HashMap<String, List<String>>();
        //adding parent data
        listDataHeader.add("Chest");
        listDataHeader.add("Back");
        listDataHeader.add("Shoulders");
        listDataHeader.add("Quadriceps");
        listDataHeader.add("Hamstring");
        listDataHeader.add("Biceps");
        listDataHeader.add("Triceps");

        List<String> chestEx = new ArrayList<String>();
        chestEx.add("Push Ups");
        chestEx.add("Bench Press");
        chestEx.add("Cable Crossover");
        chestEx.add("Pec Deck");
        listDataChild.put(listDataHeader.get(0), chestEx);

        List<String> backEx = new ArrayList<String>();
        backEx.add("Pull Ups");
        backEx.add("Chin Ups");
        backEx.add("Lat Pull-downs");
        backEx.add("Dumbbell Row");
        backEx.add("Dumbbell Shrugs");
        listDataChild.put(listDataHeader.get(1), backEx);

        List<String> shoulderEx = new ArrayList<String>();
        shoulderEx.add("Overhead Dumbbell Press");
        shoulderEx.add("Overhead Machine Press");
        shoulderEx.add("Arnold Press");
        shoulderEx.add("Upright Rows");
        shoulderEx.add("Rear Deltoid Rows/Raises/Flyes");
        listDataChild.put(listDataHeader.get(2), shoulderEx);

        List<String> quadricepsEx = new ArrayList<String>();
        quadricepsEx.add("Squats");
        quadricepsEx.add("Lunges");
        quadricepsEx.add("Step-ups");
        quadricepsEx.add("Leg Press");
        quadricepsEx.add("Leg Extensions");
        listDataChild.put(listDataHeader.get(3), shoulderEx);

        List<String> hamstringEx = new ArrayList<String>();
        hamstringEx.add("Deadlifts");
        hamstringEx.add("Hyperextensions");
        hamstringEx.add("Glute/Ham raises");
        hamstringEx.add("Leg Curls");
        hamstringEx.add("Cable Pull-Throughs");
        listDataChild.put(listDataHeader.get(4), hamstringEx);

        List<String> bicepEx = new ArrayList<String>();
        bicepEx.add("Cable Curls");
        bicepEx.add("Machine Curls");
        bicepEx.add("Dumbbell Curls");
        bicepEx.add("Barbell Curls");
        listDataChild.put(listDataHeader.get(5), bicepEx);

        List<String> tricepEx = new ArrayList<String>();
        tricepEx.add("Dips");
        tricepEx.add("Bench Press");
        tricepEx.add("Close Grip Push-Ups");
        tricepEx.add("Tricep Extensions");
        tricepEx.add("Skull Crushers");
        listDataChild.put(listDataHeader.get(6), tricepEx);
    



exercises.Java(片段类[选项卡式应用程序])

package com.example.rowan.assignment1;



import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;

import java.io.FileInputStream;
import java.io.ObjectInputStream;


/**
 * A simple @link Fragment subclass.
 */
public class exercises extends Fragment 


    Button exButton;
    Button update;
    String muscle, exercise;

    public exercises() 
        // Required empty public constructor
    


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) 
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_exercises, container, false);


        /*muscle = getArguments().getString("muscle");
        exercise = getArguments().getString("exercise");*/



        // Insert onCreate code here
        exButton = (Button) view.findViewById(R.id.exbutton);


        /*if (muscle == "Chest") 
            exButton.setBackgroundResource(R.mipmap.chest);
            exButton.setText(exercise);
        */

        exButton.setOnClickListener(new View.OnClickListener() 
            public void onClick(View view) 
                // on click move to intent with expandable listView for selection
                Intent intent = new Intent(getActivity(), exerciseList.class);
                startActivity(intent);

            
        );


        return view;
    

    public static exercises newInstance() 
        exercises fragment = new
                exercises();
        return fragment;
    
    //Function from failed attempt
    /*public void setData(String m, String e)
        muscle = m;
        exercise = e;
    */



任何帮助或指点将不胜感激

【问题讨论】:

【参考方案1】:

我已经解决了这个问题,Albiet 可能有更好的解决方案。 我已将一个 Intent 从 exerciseList.Java 传递给 MainActivity.Java

    Intent intent = new Intent(getApplicationContext(),
                            MainActivity.class);

                    //Data
                    intent.putExtra("muscle", muscle);
                    intent.putExtra("exercise", exercise);
                    intent.putExtra("frag", 1);

                    startActivity(intent);

然后我将 MainActivity.Java 中的数据传递给了 exercise.Java(片段)

 Intent intent = getIntent();
        int frag = intent.getIntExtra("frag",0);
 if (frag == 1)
            muscle = intent.getStringExtra("muscle");
            exercise = intent.getStringExtra("exercise");
            //exercises is menu item 1 (mainActivity is 0)
            mViewPager.setCurrentItem(frag);
        
//Another section of code
 public String getMuscle()
        return muscle;
    

    public String getExercise()
        return exercise;
    

最后我访问了exercises.Java中的数据

MainActivity activity = (MainActivity) getActivity();

            muscle = activity.getMuscle();
            exercise = activity.getExercise();

【讨论】:

以上是关于从 Fragment 创建 Intent 并将数据从 Intent 活动传回 Fragment(选项卡式应用程序)的主要内容,如果未能解决你的问题,请参考以下文章

Intent 不会从 Fragment 启动 Activity

例外:从意图存储ArrayList时“无法转换为java.util.ArrayList”

Android Kotlin:在 Fragment 下带有 Intent 的 setOnClickListener

如何将数据从Activity返回到Fragment

Activity和Fragment之间的通信用于发送值

如何在一个fragment中更新另一个fragment