java - 在同一 Activity 的 2 个 fragment 之间发送 ArrayList

标签 java android listview android-fragments arraylist

我有 2 个 fragment 和一个 Activity 。 fragment 1 有一个带有 ListView 和一些按钮等的相对布局, Fragment 2 在底部有一个 ListView 和一个按钮。 fragment 2 的 ListView 是一个 ListView ,您可以在其中选择多个项目,当一个项目被选中时,它被添加到一个 arraylist(我们将称之为选中)或者如果取消选择则被删除,我想将这个 arrayList 发送到 Fragment 1,它在那里可以将它添加到它自己的 ListView (以及它的其他项目,如果它们存在)。我已将选定的 ArrayList 存储在 Activity 中。

Activity 有以下代码

public class AddExerciseActivity extends AppCompatActivity implements ActionBar.TabListener {

/**
 * 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}.
 */
SectionsPagerAdapter mSectionsPagerAdapter;

/**
 * The {@link ViewPager} that will host the section contents.
 */
ViewPager mViewPager;
static ArrayList<Set> sets = new ArrayList<>();

String name, date;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_fragment);
    Bundle extras = getIntent().getExtras();
    if (extras != null) {
        name = extras.getString("ExerciseName");
        date = extras.getString("date");
    }

    // Set up the action bar.
    final ActionBar actionBar = getSupportActionBar();
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
    actionBar.setTitle(name);

    // 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.pager);
    mViewPager.setAdapter(mSectionsPagerAdapter);

    // When swiping between different sections, select the corresponding
    // tab. We can also use ActionBar.Tab#select() to do this if we have
    // a reference to the Tab.
    mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
        @Override
        public void onPageSelected(int position) {
            actionBar.setSelectedNavigationItem(position);
        }
    });

    // For each of the sections in the app, add a tab to the action bar.
    for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
        // Create a tab with text corresponding to the page title defined by
        // the adapter. Also specify this Activity object, which implements
        // the TabListener interface, as the callback (listener) for when
        // this tab is selected.
        actionBar.addTab(
                actionBar.newTab()
                        .setText(mSectionsPagerAdapter.getPageTitle(i))
                        .setTabListener(this));
    }
}

@Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
    // When the given tab is selected, switch to the corresponding page in
    // the ViewPager.
    mViewPager.setCurrentItem(tab.getPosition());
}

@Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}

@Override
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}




/**
 * 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:
                Bundle bundle = new Bundle();
                bundle.putString("date", date);
                bundle.putInt("position", position);
                return new FirstFragment();
            case 1:
                return new SecondFragment();
        }
        return null;
    }

    @Override
    public int getCount() {
        // Show 3 total pages.
        return 2;
    }



    @Override
    public CharSequence getPageTitle(int position) {
        switch (position) {
            case 0:
                return "Track";
            case 1:
                return "History";
        }
        return null;
    }
}

public ArrayList<Set> getSets() {
    return sets;
}

public void setSets(ArrayList<Set> sets) {
    this.sets = sets;
}
}

这是 fragment 1

public class FirstFragment  extends android.support.v4.app.Fragment {

CardDatabaseAdapter2 mCardDatabaseAdapter2;

TextView workoutName;
EditText weight, reps;
double weightCount;
int repsCount;
ListView list;
Button plus, plus2, minus, minus2, update;
String name, date;
int type, category, count;
Exercise ex;
Card card;
View rootView;
ArrayList<Set> array = new ArrayList<>();
private AddExerciseAdapter mAddExerciseAdapter;


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    rootView = inflater.inflate(R.layout.add_exercise_view, container, false);
    setHasOptionsMenu(true);
    Bundle extras = getActivity().getIntent().getExtras();
    if (extras != null) {
        name = extras.getString("ExerciseName");
        type = extras.getInt("ExerciseType");
        category = extras.getInt("ExerciseCategory");
        date = extras.getString("date");
        Log.v("date", date);
    }
    mCardDatabaseAdapter2 = new CardDatabaseAdapter2(getActivity());

    Log.v("created", "item created");

    //mCardDatabaseAdapter2.insert(name, date);
    card = new Card(0, name, date);
    Log.v("name & date", name + "  " + date);

    ex = new Exercise(name, type, category);
    Log.v("Exercise Recieved", ex.toString());
    workoutName = (TextView) rootView.findViewById(R.id.name);
    weight = (EditText) rootView.findViewById(R.id.textWeight);
    reps = (EditText) rootView.findViewById(R.id.textRep);
    list = (ListView) rootView.findViewById(R.id.rowReps);
    plus = (Button) rootView.findViewById(R.id.plus);
    minus = (Button) rootView.findViewById(R.id.minus);
    plus2 = (Button) rootView.findViewById(R.id.plus2);
    minus2 = (Button) rootView.findViewById(R.id.minus2);
    update = (Button) rootView.findViewById(R.id.update);

    weightCount = 0;
    repsCount = 0;
    count = 1;

    array = new ArrayList<>();
    plus.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (!weight.getText().toString().equals("")) {
                weightCount = Double.parseDouble(weight.getText().toString());
                weightCount = weightCount + 2.5;
                weight.setText(String.valueOf(weightCount));
            } else {
                weight.setText(String.valueOf(2.5));
            }
        }
    });

    minus.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if(weightCount <= 0.0 || weight.getText().toString().equals("")) {
                weight.setText(String.valueOf(0.0));
            } else {
                weightCount = Double.parseDouble(weight.getText().toString());
                weightCount = weightCount - 2.5;
                weight.setText(String.valueOf(weightCount));
            }
        }
    });

    plus2.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (!reps.getText().toString().equals("")) {
                repsCount = Integer.parseInt(reps.getText().toString());
                repsCount = repsCount + 1;
                reps.setText(String.valueOf(repsCount));
            } else {
                reps.setText(String.valueOf(0));
            }
        }
    });

    minus2.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if(repsCount <= 0 || reps.getText().toString().equals("")){
                reps.setText(String.valueOf(0));
            } else {
                repsCount = Integer.parseInt(reps.getText().toString());
                repsCount = repsCount - 1;
                reps.setText(String.valueOf(repsCount));
            }
        }
    });

    update.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            if(weight.getText().toString().equals("") || weight.getText().toString().equals(String.valueOf(0.0))) {
                weight.setText(String.valueOf(0.0));
                Toast.makeText(getActivity(), "You need to enter a weight!", Toast.LENGTH_SHORT).show();
            }
            else if(reps.getText().toString().equals("")|| reps.getText().toString().equals(String.valueOf(0))) {
                reps.setText(String.valueOf(0));
                Toast.makeText(getActivity(), "You need to have at least 1 rep!", Toast.LENGTH_SHORT).show();
            } else {
                double temp2 = Double.parseDouble(weight.getText().toString());
                int temp3 = Integer.parseInt(reps.getText().toString());
                Set s = new Set(name, temp2, temp3, date);
                array.add(s);
                //mCardDatabaseAdapter2.insert2(mCardDatabaseAdapter2.highestID(), name, s.getWeight(), s.getReps(), date);
                //Log.v("inserted data", "id " + mCardDatabaseAdapter2.highestID() + " name " + name + " weight " + s.getWeight() + " reps " + s.getReps() + " date " + date);
                //Log.v("id", mCardDatabaseAdapter2.highestID() + "");
                mAddExerciseAdapter.notifyDataSetChanged();
                count++;
            }
        }
    });
    mAddExerciseAdapter = new AddExerciseAdapter(getActivity(), R.layout.row2, array);
    list.setAdapter(mAddExerciseAdapter);

    mAddExerciseAdapter.notifyDataSetChanged();

    return rootView;

}

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    inflater.inflate(R.menu.menu_add_exercise, menu);
}

@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();

    if (id == R.id.action_done) {
        Intent intent = new Intent(getActivity(), MainMenuActivity.class);
        if(!array.isEmpty()) {
            mCardDatabaseAdapter2.insert(name, date);
            for (Set s : array) {
                mCardDatabaseAdapter2.insert2(mCardDatabaseAdapter2.highestID(), name, s.getWeight(), s.getReps(), date);
            }
            mCardDatabaseAdapter2.resetID();
        }
        startActivity(intent);
    }

    return super.onOptionsItemSelected(item);
}


@Override
public void onPause() {
    super.onPause();
}

@Override
public void onStop() {
    super.onStop();
}

@Override
public void onResume() {
    super.onResume();
    ArrayList<Set> s = ((AddExerciseActivity)getActivity()).getSets();
    if(!s.isEmpty()) {
        for(Set t : s) {
            array.add(t);
            mAddExerciseAdapter.notifyDataSetChanged();
        }
    }
}
}

这是 fragment 2

public class SecondFragment extends Fragment {

CardDatabaseAdapter2 mCardDatabaseAdapter;
ExerciseHistoryAdapter mExerciseHistoryAdapter;
AddExerciseActivity mAddExerciseActivity;
ArrayList<Set> sets = new ArrayList<>();
ArrayList<Set> selected = new ArrayList<>();
String name;
ListView lv;
Card c;
int x;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.exercise_history, container, false);
    Bundle extras = getActivity().getIntent().getExtras();
    if (extras != null) {
        name = extras.getString("ExerciseName");
    }
    mAddExerciseActivity = new AddExerciseActivity();
    mCardDatabaseAdapter = new CardDatabaseAdapter2(getActivity());
    sets = mCardDatabaseAdapter.getAllSetsWithName(name);
    Log.v("array", sets.toString());

    lv = (ListView) rootView.findViewById(R.id.history_list);
    lv.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
    lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            if (!selected.contains(sets.get(position))) {
                lv.setItemChecked(position, true);
                view.setBackgroundColor(Color.rgb(255, 152, 0));
                Toast.makeText(getActivity(), "Item Selected", Toast.LENGTH_SHORT).show();
                selected.add(sets.get(position));
            } else {
                lv.setItemChecked(position, false);
                view.setBackgroundColor(Color.rgb(221, 221, 221));
                selected.remove(sets.get(position));
                Toast.makeText(getActivity(), "Item Unselected", Toast.LENGTH_SHORT).show();
            }
        }
    });



    Button add = (Button) rootView.findViewById(R.id.add_button);
    add.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
                    ((AddExerciseActivity)getActivity()).setSets(selected);

                    Toast.makeText(getActivity(), "items have been added successfully", Toast.LENGTH_SHORT).show();
        }
    });

    mExerciseHistoryAdapter= new ExerciseHistoryAdapter(getActivity(), R.layout.history_listview_item, sets, lv);
    lv.setAdapter(mExerciseHistoryAdapter);

    return rootView;
}
}

编辑:我的尝试就在那里,我在那里获取/设置 arrayList。但它不起作用,因为 fragment 已经创建。

编辑 2:

04-23 20:18:48.034      598-598/com.company.joeliomason.projectmeE/InputEventReceiver﹕ Exceptiondispatching input event.
04-23 20:18:48.034      598-598/com.company.joeliomason.projectme
E/MessageQueue-JNI﹕ Exception in MessageQueue callback: 
handleReceiveCallback
04-23 20:18:48.034      598-598/com.company.joeliomason.projectme 
E/MessageQueue-JNI﹕ java.lang.IllegalStateException: Fragment already 
active
        at android.support.v4.app.Fragment.setArguments(Fragment.java:549)
        at com.company.joeliomason.projectme.Views.FirstFragment.setArguments(FirstFragment.java:200)
        at com.company.joeliomason.projectme.Views.AddExerciseActivity.onTabSelected(AddExerciseActivity.java:94)
        at android.support.v7.internal.app.WindowDecorActionBar.selectTab(WindowDecorActionBar.java:640)
        at android.support.v7.internal.app.WindowDecorActionBar.setSelectedNavigationItem(WindowDecorActionBar.java:414)
        at com.company.joeliomason.projectme.Views.AddExerciseActivity$1.onPageSelected(AddExerciseActivity.java:68)

最佳答案

这可能有效,但我还没有测试过。 看起来您可以在 onTabSelected() 方法中使用新方法调用来传递 Bundle

AddExerciseActivity 中创建对 FirstFragment 的引用作为实例变量:

ViewPager mViewPager;
static ArrayList<Set> sets = new ArrayList<>();
FirstFragment fragmentFirst; //added

在您的 SectionsPagerAdapter 中设置它:

@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:
                Bundle bundle = new Bundle();
                bundle.putString("date", date);
                bundle.putInt("position", position);
                fragmentFirst = new FirstFragment(); //modified
                return fragmentFirst; //added
            case 1:
                return new SecondFragment();
        }
        return null;
    }

然后,添加,添加sets到一个Bundle,并传入onTabSelected中的FirstFragment:

@Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
    // When the given tab is selected, switch to the corresponding page in
    // the ViewPager.
    mViewPager.setCurrentItem(tab.getPosition());

    if (fragmentFirst != null){
       Bundle bundle = new Bundle();
       bundle.putSerializable("sets", sets);
       //fragmentFirst.setArguments(bundle); //not working
       fragmentFirst.updateArguments(bundle); //try this
    }

}

编辑:在 FragmentFirst 中添加一个新的公共(public)方法:

public void updateArguments(Bundle args) { 
     ArrayList<Set> x = new ArrayList<>(); 
     x = (ArrayList<Set>) args.getSerializable("sets"); 
     for(Set p: x) { 
        array.add(p); 
     } 
     mAddExerciseAdapter.notifyDataSetChanged(); 
   } 

关于java - 在同一 Activity 的 2 个 fragment 之间发送 ArrayList,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29829985/

相关文章:

java - 单元工作克隆 sqlite 中的主键为空或零

java - 反射中获取方法参数的类型

java - 用于接口(interface)和其中带注释的方法的 Spring AOP

android - 如何解决 ListView 布局和 IME 预测文本之间的竞争条件

java - FTP 中的 GET 请求

Android 小部件大小

Android - E/Surface:queueBuffer : error queuing buffer to SurfaceTexture, -22 崩溃

android - Google 云端硬盘 SDK 客户端 ID

android - 无法单击其行由 WebView 组成的 ListView

android - 单击 ListView 中的特定项目时,如何将 ListView 的选中项目框的颜色设置为绿色以外的其他颜色?