java - 切换选项卡时保存 fragment 数据

标签 java android android-fragments android-viewpager android-tabs

我编写了一个游戏,其中用户输入玩家数量,每个玩家都会获得一个带有空表的自己的选项卡。

因此,我使用了 PagerAdapterClass (扩展 FragmentStatePagerAdapter)和 viewpager。 所以每个玩家都有相同的fragmentView

现在用户可以将变量放入表中,但是每次我在选项卡之间切换时,输入都会丢失。 好吧,我通过将其添加到我的 pageradapter 来“解决”了这个问题:

@Override
    public void destroyItem(ViewGroup container, int position, Object object) {

    }

但它更多的是阻止 View 页面破坏而不是实际保存数据。

我的主要目标是真正保存该表中的内容。

我已经尝试过 https://stackoverflow.com/a/17135346/11956040但我无法获取 mContent,因为我无法获取 fragment 的引用,因为所有 fragment 都不是自己创建的,而是同时创建的(或类似的东西)。

我也不知道如何设置标签。 这样:https://stackoverflow.com/a/18993042/11956040 对我不起作用。

主要 Activity :

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_game);
        Toolbar toolbar = findViewById(R.id.toolbar2);
        setSupportActionBar(toolbar);

        ...

        //numPlayer = num of tabs
        SectionsPagerAdapter adapter = new SectionsPagerAdapter(numPlayer, getSupportFragmentManager());

        ViewPager viewPager = findViewById(R.id.view_pager);
        viewPager.setAdapter(adapter);

        TabLayout tabs = findViewById(R.id.tabs);
        tabs.setupWithViewPager(viewPager);
        if(numPlayer >= 5) {
            tabs.setTabMode(TabLayout.MODE_SCROLLABLE);
        }
    }

寻呼机适配器:

public class SectionsPagerAdapter extends FragmentStatePagerAdapter {

    private int tabNum;

    public SectionsPagerAdapter(int tabNum, FragmentManager fm) {
        super(fm);
        this.tabNum = tabNum;
    }

    @Override
    public PlaceholderFragment getItem(int position) {
        return PlaceholderFragment.newInstance(position);
    }

    @Nullable
    @Override
    public CharSequence getPageTitle(int position) {
        int playerNum = position + 1;
        return "Spieler " + playerNum;
    }

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

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {

    }
}

fragment :

public static PlaceholderFragment newInstance(int index) {
        PlaceholderFragment fragment = new PlaceholderFragment();
        Bundle bundle = new Bundle();
        bundle.putInt("player", index);
        fragment.setArguments(bundle);
        return fragment;
    }

一定有一个解决方案,但我找不到它或无法实现它。 请帮忙。

最佳答案

这样解决了我的问题:

  1. 定义行和列的二维ArrayList以及列的计数器:
    private ArrayList<ArrayList<Integer>> columnArray; 
    private int column;
  • onCreateView(对于 fragment )设置 column = 0 并向 columnArray 添加一个带有空列表的条目 并在 columnArray 的列索引上设置第一个 rowList:
  • pointArray.add(column, new ArrayList<Integer>());
    final ArrayList<Integer> rowList = pointArray.get(column);
    
  • 用 0 填充空的 rowList(也许它也可以以其他方式工作,但我这样做是为了在空的 EditTexts 上添加 0 并且可以轻松替换它们)

  • 为所有 EditText 定义 View.OnFocusChangeListener,如下所示:

  • /*I dont know if I could set column final in general, 
    but you need to set a final int because you call this value in an inner class*/
    
    final int pos = column 
    
    for (int i = 0; i <= getEditTexts(pos).size() - 1; i++) {
    EditText editTexts = getEditTexts(pos).get(i);
    final String editTextsTag = editTexts.getTag().toString();
    
    View.OnFocusChangeListener listener = new View.OnFocusChangeListener() {
       @Override
       public void onFocusChange(View view, final boolean b) {
          if (view.getTag().toString().equals(editTextsTag) && !b) {
            //fills rowList
            addEntries(pos, rowList);
    
            //adds rowList to columnArray
            columnArray.set(pos, rowList);
    
            //save the columnsArray or use it 
            saveData(columnArray);
          }
       }
    };
    editTexts.setOnFocusChangeListener(listener);
    
  • 定义从每个单元格收集数据的方法,具体取决于列位置(pos),将其添加到 rowList 例如:
  • private void addEntries(int pos, ArrayList<Integer> rowList) {
       for(int i = 0; i <= 16; i++) {
          //this requires EditText_label, i made them dynamically
          String edit_label = "edit_" + pos + i; 
          EditText editText = table.findViewWithTag(edit_label);
          String mEditTextString = editText.getText().toString();
    
          try {
             int thisValue = Integer.parseInt(mEditString);
             rowList.set(j, thisValue);
          } catch (NumberFormatException e) {
             //maybe you do not need this, but I need it for something else
             int thisValue = 0;
             rowList.set(j, thisValue);
          }
       }
    }
    
  • 定义保存columnArray的方法。我使用一个接口(interface)将其提供给父 Activity: Here you can find how I made it 否则,您可以将columnArray 转换为字符串并将其保存在数据库中。
  • 注意

    我使用列值集来实现它,因为我使用一种方法增加了在运行时添加的每一列的值。如果只有一列,则不需要设置它。只需使用 0 代替 pos、column

    关于java - 切换选项卡时保存 fragment 数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57610507/

    相关文章:

    java - 是什么让引用比较 (==) 对 Java 中的某些字符串起作用?

    Java:一般返回由参数指定的类型化Set

    android - Bundle 数据未在从服务中的通知传递的 Activity 中更新,始终填充第一个 bundle

    android - 交错网格布局管理器动态列数

    java - showAsAction ="always"在双 Pane 模式下不起作用

    java - 将 ArrayList<Object> 存储在 Bundle 中以供 Fragment 使用

    java - IBM WAS apache httpcore 和 httpclient

    java - 在焦点 slider 上按 Tab 时,RangeSlider 会导致 NullPointerException

    android - M2E 不适用于现有的 Maven 项目

    java - 单击 RecyclerView 中的项目时出现问题