我已经为此苦了一段时间了。我有一个由库模块和应用程序模块组成的相当复杂的系统。

库模块包含
活动:AbstractActivity 片段:AbstractFragment
应用模块包含
活动:WineListActivity(-> AbstractListActivity)
片段:WineListFragment和EditWineFragment(-> AbstractList&AbstractEdit片段)

在启动时,将加载WineListActivity并与WineListFragment一起显示。从列表中选择葡萄酒时,片段将被EditFragment替换。当用户按下“后退”或“保存”按钮时,应用程序应在按下时执行活动,并再次显示WineListFragment。这是发生崩溃的地方。任何帮助,将不胜感激。我已经研究了一段时间了。错误:

09-12 20:50:50.625 4148-4148/com.toteki.winetaster E/AndroidRuntime: FATAL EXCEPTION: main
09-12 20:50:50.625 4148-4148/com.toteki.winetaster E/AndroidRuntime: Process: com.toteki.winetaster, PID: 4148
09-12 20:50:50.625 4148-4148/com.toteki.winetaster E/AndroidRuntime: java.lang.IllegalArgumentException: No view found for id 0x7f0c004f (com.toteki.winetaster:id/content_container) for fragment WineListFragment{423e51d0 #0 id=0x7f0c004f}
09-12 20:50:50.625 4148-4148/com.toteki.winetaster E/AndroidRuntime:     at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1018)
09-12 20:50:50.625 4148-4148/com.toteki.winetaster E/AndroidRuntime:     at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1207)
09-12 20:50:50.625 4148-4148/com.toteki.winetaster E/AndroidRuntime:     at android.support.v4.app.BackStackRecord.popFromBackStack(BackStackRecord.java:958)
09-12 20:50:50.625 4148-4148/com.toteki.winetaster E/AndroidRuntime:     at android.support.v4.app.FragmentManagerImpl.popBackStackState(FragmentManager.java:1625)
09-12 20:50:50.625 4148-4148/com.toteki.winetaster E/AndroidRuntime:     at android.support.v4.app.FragmentManagerImpl.popBackStackImmediate(FragmentManager.java:561)
09-12 20:50:50.625 4148-4148/com.toteki.winetaster E/AndroidRuntime:     at android.support.v4.app.FragmentActivity.onBackPressed(FragmentActivity.java:166)
09-12 20:50:50.625 4148-4148/com.toteki.winetaster E/AndroidRuntime:     at android.app.Activity.onKeyUp(Activity.java:2193)
09-12 20:50:50.625 4148-4148/com.toteki.winetaster E/AndroidRuntime:     at android.view.KeyEvent.dispatch(KeyEvent.java:2664)
09-12 20:50:50.625 4148-4148/com.toteki.winetaster E/AndroidRuntime:     at android.app.Activity.dispatchKeyEvent(Activity.java:2423)
09-12 20:50:50.625 4148-4148/com.toteki.winetaster E/AndroidRuntime:     at android.support.v7.internal.view.WindowCallbackWrapper.dispatchKeyEvent(WindowCallbackWrapper.java:50)
09-12 20:50:50.625 4148-4148/com.toteki.winetaster E/AndroidRuntime:     at android.support.v7.app.AppCompatDelegateImplBase$AppCompatWindowCallbackBase.dispatchKeyEvent(AppCompatDelegateImplBase.java:224)
09-12 20:50:50.625 4148-4148/com.toteki.winetaster E/AndroidRuntime:     at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:2017)
09-12 20:50:50.625 4148-4148/com.toteki.winetaster E/AndroidRuntime:     at android.view.ViewRootImpl$ViewPostImeInputStage.processKeyEvent(ViewRootImpl.java:3848)
09-12 20:50:50.625 4148-4148/com.toteki.winetaster E/AndroidRuntime:     at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:3822)
09-12 20:50:50.625 4148-4148/com.toteki.winetaster E/AndroidRuntime:     at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3395)
09-12 20:50:50.625 4148-4148/com.toteki.winetaster E/AndroidRuntime:     at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3445)
09-12 20:50:50.625 4148-4148/com.toteki.winetaster E/AndroidRuntime:     at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3414)
09-12 20:50:50.625 4148-4148/com.toteki.winetaster E/AndroidRuntime:     at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3521)
09-12 20:50:50.625 4148-4148/com.toteki.winetaster E/AndroidRuntime:     at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3422)
09-12 20:50:50.625 4148-4148/com.toteki.winetaster E/AndroidRuntime:     at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3578)
09-12 20:50:50.625 4148-4148/com.toteki.winetaster E/AndroidRuntime:     at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3395)
09-12 20:50:50.625 4148-4148/com.toteki.winetaster E/AndroidRuntime:     at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3445)
09-12 20:50:50.625 4148-4148/com.toteki.winetaster E/AndroidRuntime:     at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3414)
09-12 20:50:50.625 4148-4148/com.toteki.winetaster E/AndroidRuntime:     at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3422)
09-12 20:50:50.625 4148-4148/com.toteki.winetaster E/AndroidRuntime:     at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3395)
09-12 20:50:50.625 4148-4148/com.toteki.winetaster E/AndroidRuntime:     at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3445)
09-12 20:50:50.625 4148-4148/com.toteki.winetaster E/AndroidRuntime:     at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3414)
09-12 20:50:50.625 4148-4148/com.toteki.winetaster E/AndroidRuntime:     at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3554)
09-12 20:50:50.625 4148-4148/com.toteki.winetaster E/AndroidRuntime:     at android.view.ViewRootImpl$ImeInputStage.onFinishedInputEvent(ViewRootImpl.java:3714)
09-12 20:50:50.625 4148-4148/com.toteki.winetaster E/AndroidRuntime:     at android.view.inputmethod.InputMethodManager$PendingEvent.run(InputMethodManager.java:2021)
09-12 20:50:50.625 4148-4148/com.toteki.winetaster E/AndroidRuntime:     at android.view.inputmethod.InputMethodManager.invokeFinishedInputEventCallback(InputMethodManager.java:1715)
09-12 20:50:50.625 4148-4148/com.toteki.winetaster E/AndroidRuntime:     at android.view.inputmethod.InputMethodManager.finishedInputEvent(InputMethodManager.java:1706)
09-12 20:50:50.625 4148-4148/com.toteki.winetaster E/AndroidRuntime:     at android.view.inputmethod.InputMethodManager$ImeInputEventSender.onInputEventFinished(InputMethodManager.java:1998)
09-12 20:50:50.625 4148-4148/com.toteki.winetaster E/AndroidRuntime:     at android.view.InputEventSender.dispatchInputEventFinished(InputEventSender.java:141)
09-12 20:50:50.625 4148-4148/com.toteki.winetaster E/AndroidRuntime:     at android.os.MessageQueue.nativePollOnce(Native Method)
09-12 20:50:50.625 4148-4148/com.toteki.winetaster E/AndroidRuntime:     at android.os.MessageQueue.next(MessageQueue.java:138)
09-12 20:50:50.625 4148-4148/com.toteki.winetaster E/AndroidRuntime:     at android.os.Looper.loop(Looper.java:123)
09-12 20:50:50.625 4148-4148/com.toteki.winetaster E/AndroidRuntime:     at android.app.ActivityThread.main(ActivityThread.java:5146)
09-12 20:50:50.625 4148-4148/com.toteki.winetaster E/AndroidRuntime:     at java.lang.reflect.Method.invokeNative(Native Method)
09-12 20:50:50.625 4148-4148/com.toteki.winetaster E/AndroidRuntime:     at java.lang.reflect.Method.invoke(Method.java:515)
09-12 20:50:50.625 4148-4148/com.toteki.winetaster E/AndroidRuntime:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:732)
09-12 20:50:50.625 4148-4148/com.toteki.winetaster E/AndroidRuntime:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:566)
09-12 20:50:50.625 4148-4148/com.toteki.winetaster E/AndroidRuntime:     at dalvik.system.NativeStart.main(Native Method)


类:
抽象活动

public abstract class AbstractActivity extends AppCompatActivity {
    public final static String TAG = "AbstractActivity";

    protected AbstractFragment fragment;

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

        Log.d(TAG, "onCreate");

        setContentView(R.layout.activity_abstract);
    }

    public void addFragment(AbstractFragment fragment) {
        Log.d(TAG, "addFragment");

        this.fragment = fragment;

        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();

        transaction.addToBackStack(this.fragment.TAG);

        transaction.add(com.toteki.library.R.id.content_container, this.fragment, this.fragment.TAG).commit();
    }

    public void replaceFragment(AbstractFragment fragment, boolean addToBackStack) {
        Log.d(TAG, "replaceFragment");

        this.fragment = fragment;

        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();

        if(addToBackStack) {
            transaction.addToBackStack(this.fragment.TAG);
        }

        transaction.replace(com.toteki.library.R.id.content_container, this.fragment, this.fragment.TAG).commit();
    }

    public abstract void onTaskSuccessful(String tag);
    public abstract void onTaskFailure(String tag);
}


WineListActivity

public class WineListActivity extends AbstractListActivity {
    public final static String TAG = "WineListActivity";

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

        Log.d(TAG, "onCreate");

        WineDataSource.instance().open(this);
        WineDataSource.instance().delete();
        WineDataSource.instance().close(this);

        addFragment(new WineListFragment());
    }

    @Override
    public void onListItemClicked(Rateable r) {
        Bundle bundle = new Bundle();
        bundle.putSerializable("currentWine", r);

        AbstractFragment fragment = new EditWineFragment();
        fragment.setArguments(bundle);

        replaceFragment(fragment, true);
    }
}


WineListFragment

public class WineListFragment extends AbstractListFragment {
    public final static String TAG = "WineListFragment";

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

        Log.d(TAG, "onCreate");

        for(int i = 0; i < 5; i++) {
            Wine w = new Wine();
            w.setName("Test " + i);
            WineController.instance().create(w);
        }

        adapter = new WineListAdapter(activity, WineController.instance().getList());
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View v = super.onCreateView(inflater, container, savedInstanceState);

        list.setAdapter(adapter);

        return v;
    }
}


WineListAdapter

public class WineListAdapter extends RecyclerView.Adapter {
    private AbstractActivity activity;
    private List<Wine> wineList;

    public WineListAdapter(AbstractActivity activity, List<Wine> wineList) {
        this.activity = activity;
        this.wineList = wineList;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_wine_list, parent, false);

        return new ViewHolder(v);
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        final Wine wine = wineList.get(position);
        ((ViewHolder) holder).getBinding().setVariable(BR.wine, wine);
        ((ViewHolder) holder).getBinding().executePendingBindings();
    }

    @Override
    public int getItemCount() {
        return wineList.size();
    }

    private class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        private ItemWineListBinding binding;

        public ViewHolder(View v) {
            super(v);

            v.setOnClickListener(this);

            binding = DataBindingUtil.bind(v);
        }

        public ViewDataBinding getBinding() {
            return binding;
        }

        @Override
        public void onClick(View view) {
            ((AbstractListActivity) activity).onListItemClicked(binding.getWine());
        }
    }
}


EditWineFragment

public class EditWineFragment extends AbstractEditFragment {
    public final static String TAG = "EditWineFragment";

    private FragmentEditWineBinding currentWineBinding;

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

        Log.d(TAG, "onCreate");

        Bundle bundle = this.getArguments();
        if (bundle != null) {
            currentRateable = (Wine) bundle.getSerializable("currentWine");
        }

        if(currentRateable == null) {
            currentRateable = new Wine();
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment_edit_wine, container, false);

        currentWineBinding = DataBindingUtil.setContentView(activity, R.layout.fragment_edit_wine);
        currentWineBinding.setWine((Wine) currentRateable);

        return v;
    }

    protected void actionSave() {
        activity.onBackPressed();

        currentRateable = currentWineBinding.getWine();
        new CreateTask(activity, WineDataSource.instance(), WineController.instance()).execute(currentRateable);
    }
}


acitivty_abstract.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:id="@+id/content_container"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#f9d107">
    </LinearLayout>

</LinearLayout>


fragment_edit_wine.xml

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:custom="http://schemas.android.com/apk/res-auto" >
    <data>
        <variable name="wine" type="com.toteki.winetaster.model.Wine"/>
    </data>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="@dimen/margin_medium"
        android:background="#e90f0f">

        <com.toteki.library.view.CustomEditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/editText"
            android:layout_alignParentTop="true"
            android:layout_alignParentStart="true"
            custom:input="@{wine.name}"
            custom:header="@string/header_name"
            custom:hint="@string/hint_name"
            android:background="#09ef06" />
    </RelativeLayout>
</layout>


编辑:我删除了EditWineFragment的onCreateView,按返回按钮后一切正常(除了未显示实际布局)。所以我猜想我为EditWineFragment创建/添加视图布局的方式就是问题。但是我不确定到底出了什么问题。

最佳答案

问题出在数据绑定上。根据setContentView的文档,活动的布局已替换:


将活动的内容视图设置为给定的布局,并返回关联的绑定。


因此,当您结束片段并且FragmentManager尝试恢复WineListFragment时,content_container消失了。因此,之前的片段无法放置在布局中,并且会引发异常。

09-27 05:46