RecyclerView的片段直到更改方向才会显示第二次

时间:2019-04-04 09:42:44

标签: android android-fragments android-recyclerview

我有一个包含RecyclerView和一个按钮的片段。按下上一个片段中的按钮(会添加一些数据)时,将显示该片段,然后回收站显示正确填充的内容,该按钮将起作用。然后,我回到上一个片段,再次按下按钮(添加更多数据),并且同一段代码显示相同的片段,但是RecyclerView未填充,并且该按钮不起作用。通过阅读此question,我的猜测是我正在片段管理中做某件事-因为一旦我改变方向并重新创建了片段,列表就可以很好地显示,并且按钮可以正常工作。

这就是我正在对片段进行的管理-我从互联网上的一个示例中获取了信息,但我担心它是不正确的

首先有一个我为片段制作的基类:

public class BaseFragment extends Fragment {

    private AbstractFragmentCallback mCallback;


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

        try {
            mCallback = (AbstractFragmentCallback) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                + " must implement " + 
AbstractFragmentCallback.class.getCanonicalName());
        }

    }

    /**
     * This method replaces the currently shown fragment with a new 
fragment of a particular class.
     * If a fragment of the required class already shown - does 
nothing.
     * @param clazz the class of the fragment to show
     * @param addToBackStack whether the replacement should be added 
to back-stack
     * @param args arguments for the newly created fragment (can be 
null)
     */
    public void replaceFragment(Class<? extends Fragment> clazz, 
boolean addToBackStack,
                            Bundle args) {
        mCallback.replaceFragment(clazz, addToBackStack, args);
    }



    public interface AbstractFragmentCallback {

        /**
         * Call to this method replaces the currently shown fragment 
with a new one
         *
         * @param clazz           the class of the new fragment
         * @param addToBackStack whether the old fragment should be 
added to the back stack
         * @param args           arguments to be set for the new fragment
         */
        void replaceFragment(Class<? extends Fragment> clazz, boolean addToBackStack,
                         Bundle args);

    }

}

因此,我的MainActivity然后实现了BaseFragment.AbstractfragmentCallback:

public class MainActivity extends AppCompatActivity implements BaseFragment.AbstractFragmentCallback {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(....);

    if (null == savedInstanceState) {
        replaceFragment(WelcomeFragment.class, false, null);
    }
}

// ---------------------------------------------------------------------------------------------
//
// Fragments management

@Override
public void replaceFragment(Class<? extends Fragment> clazz, boolean addToBackStack,
                            Bundle args) {
    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();

    Fragment newFragment;

    try {
        // Create new fragment
        newFragment = clazz.newInstance();
        if (args != null) newFragment.setArguments(args);
    } catch (InstantiationException e) {
        e.printStackTrace();
        return;
    } catch (IllegalAccessException e) {
        e.printStackTrace();
        return;
    }

    if (addToBackStack) {
        ft.addToBackStack(null);
    }

    // Change to a new fragment
    ft.replace(R.id.container, newFragment, clazz.getName());
    ft.commit();

}
// End of fragments management
//
// ---------------------------------------------------------------------------------------------

}

当我的带有按钮的片段想要调出列表片段时,它将调用

replaceFragment(ListFragment.class, true, null);

所以-显然,ListFragemnt出现了,并且它的所有代码都触发了,包括重新获取RecyclerView并重新填充它-我什至看到适配器中的所有代码都针对每个项目被调用-但这些项目没有出现在列表

public class ListFragment extends BaseFragment implements ListFragmentMvc.ListViewMvcListener {

private List<MyStuff> stuffList;

@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstance) {
    stuffList = new ArrayList<>();
    return inflater.inflate(R.layout.list_activity, container, true);
}

@Override
public void onResume() {
    super.onResume();
    recyclerView = mRootView.findViewById(R.id.recycler_view);


    letsGoButton = mRootView.findViewById(R.id.lets_go_button);
    letsGoButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Activity activity = getActivity();
    if (activity != null) {
        getActivity().onBackPressed();
    }

        }
    });

    recyclerView.setItemAnimator(new DefaultItemAnimator());

    DividerItemDecoration itemDecor = new DividerItemDecoration(context, HORIZONTAL);
    recyclerView.addItemDecoration(itemDecor);

    RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(context);
    recyclerView.setLayoutManager(mLayoutManager);

    setData(MyApplication.getAllStuffItems());

}
public void setData(List<MyStuff> stuff) {
    stuffList = stuff;
    mAdapter = new StuffAdapter(stuffList);
    recyclerView.setAdapter(mAdapter);

    mAdapter.notifyDataSetChanged();
}


}

因此,有人知道为什么直到我重新输入listFragment改变方向后,这才起作用?

谢谢

2 个答案:

答案 0 :(得分:0)

您是否可以尝试将设置/更新recyclerView和letGoButton的代码从 onResume 方法移动到 onViewCreated 方法,如下所示:

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    recyclerView = view.findViewById(R.id.recycler_view);


    letsGoButton = view.findViewById(R.id.lets_go_button);
    letsGoButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Activity activity = getActivity();
            if (activity != null) {
                getActivity().onBackPressed();
            }

        }
    });

    recyclerView.setItemAnimator(new DefaultItemAnimator());

    DividerItemDecoration itemDecor = new DividerItemDecoration(context, HORIZONTAL);
    recyclerView.addItemDecoration(itemDecor);

    RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(context);
    recyclerView.setLayoutManager(mLayoutManager);

    setData(MyApplication.getAllStuffItems());
}

答案 1 :(得分:0)

哇,那真是浪费一天。

最后,我遇到了两个错误,它们相互粘贴并相互隐藏。

这不起作用的真正真实原因,我想是因为我应该有

return inflater.inflate(R.layout.list_activity, container, false);

代替

return inflater.inflate(R.layout.list_activity, container, true);

我在代码中撒了些谎,因为我并没有真正直接返回inflater.inflate的结果。我正在调用它(使用错误的参数),然后返回null。

我想这会教会我在发布中更加诚实