在Android上使用RecyclerView和Fragment时出错

时间:2018-11-13 02:38:44

标签: android android-fragments android-recyclerview

我正在尝试制作一个具有RecyclerView的应用程序,其中包含用于删除对象和添加随机数的选项。我想做的是单击“回收者”视图列表的任何成员时显示一个片段。我收到错误“ java.lang.IllegalStateException:活动已被破坏”。 我很确定我做错了什么。 我试图做的是在AnimalsAdapter类上调用更改片段方法。我让下面的代码和github链接。

E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.berna.recyclerviewtp2, PID: 18705
java.lang.IllegalStateException: Activity has been destroyed
    at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:2114)
    at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:683)
    at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:637)
    at com.example.berna.recyclerviewtp2.MainActivity.changeFragment(MainActivity.java:148)
    at com.example.berna.recyclerviewtp2.AnimalsAdapter$1.onClick(AnimalsAdapter.java:81)
    at android.view.View.performClick(View.java:6597)
    at android.view.View.performClickInternal(View.java:6574)
    at android.view.View.access$3100(View.java:778)
    at android.view.View$PerformClick.run(View.java:25885)
    at android.os.Handler.handleCallback(Handler.java:873)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:193)
    at android.app.ActivityThread.main(ActivityThread.java:6669)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

我的代码主类changeFragment:

    public void changeFragment(View view){
    Fragment fragment;
    FragmentOne fragmentOne = new FragmentOne();
    fragment = fragmentOne;
    FragmentManager fm = getSupportFragmentManager();
    FragmentTransaction ft = fm.beginTransaction();
    ft.replace(R.id.fragment,fragment);
    ft.addToBackStack(null);
    ft.commit();

FragmentOne类代码:

public class FragmentOne extends Fragment {
@Override
public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstaceState){
    //Inflate the layout for this fragment
    return inflater.inflate(R.layout.fragment_blank,container,false);
}

}

点击监听器代码:

        // Set a click listener for TextView
    holder.mTextView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            new MainActivity().changeFragment(view);
            //String animal = mDataSet.get(position);
            //Toast.makeText(mContext,animal,Toast.LENGTH_SHORT).show();
        }
    });

按下recyclerview成员时,我需要做什么以实现片段化?

Original code I'm using to try what I'm trying

Github link for complete project

3 个答案:

答案 0 :(得分:1)

永远不要以这种方式实例化活动:new MainActivity().changeFragment(view);,它永远也不能正确初始化。因此,要么委托侦听器,要么为回调找到其他解决方法。

例如,为回调创建接口:

interface ItemClickListener {
    void onItemClick(View v);
}

让您的MainActivity实现该接口:

public class MainActivity extends Activity implements ItemClickListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // ...
        mAdapter = new AnimalsAdapter(mContext, animalsList, this);
        // ...
    }

    @Override
    public void onItemClick(View view) {
        changeFragment(view);
    }
}

然后允许您的适配器将ItemClickListener作为参数:

private ItemClickListener callback;

public AnimalAdapter(Context context, List<String> data, ItemClickListener callback) {
    this.callback = callback;

然后让您的holder.mTextView转发回调(返回活动):

holder.mTextView.setOnClickListener(callback::onItemClick);

答案 1 :(得分:0)

您应该在创建活动之后创建片段,这是有关活动生命周期的基础知识。

holder.mTextView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Intent intent = new Intent(your_current_activity, MainActivity.class);
            intent.putExtras(extras);
            startActivity(intent);
        }
    });

然后替换MainActivity onCreate()中的片段

@Override
protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.your_activity_layout);
        changeFragment(null); //because we don't using parameter view

}

如果还有其他问题,请在下面评论。

答案 2 :(得分:0)

您需要在代码中进行两项更改。 1.创建一个单击侦听器的界面。 2.如果要替换片段,则还需要使用XML的另一个布局

我们解决了第一个问题。 1.创建一个单击侦听器的界面。 以下是您需要对适配器进行的一些更改,

  • 在适配器中创建接口

    公共接口RecyclerItemInteraction {         void onChangeFragmentClick();     }

  • 第二个更改将通过此接口。

    • Declare gloabal变量 私有RecyclerItemInteraction mInteraction;

      public AnimalsAdapter(上下文上下文,列表,RecyclerItemInteraction交互){     mDataSet =列表;     mContext =上下文;     mInteraction =互动; }

  • 在行下方替换 新的MainActivity()。changeFragment(view); : 去掉它 如果(mInteraction!= null)mInteraction.onChangeFragmentClick(); 添加此行。

  • 现在转到您的MainActivity并添加以下行 mAdapter = new AnimalsAdapter(mContext,animalsList,this); 您可以看到添加了第三个参数 this

  • 现在覆盖此方法,祝您愉快。

    @Override     公共无效onChangeFragmentClick(){         片段片段;         FragmentOne fragmentOne =新的FragmentOne();         片段= fragmentOne;         FragmentManager fm = getSupportFragmentManager();         FragmentTransaction ft = fm.beginTransaction();         ft.replace(R.id.container,fragment);         ft.addToBackStack(null);         ft.commit();     }

    1. 如果要替换片段,则还需要XML布局
  • 将此行添加到main_activity.xml布局中。