Android 片段适配UI(典型的双片段新闻阅读器)-在双窗格模式下缺少第一个片段

Android 片段适配UI(典型的双片段新闻阅读器)-在双窗格模式下缺少第一个片段,android,android-fragments,onconfigurationchanged,Android,Android Fragments,Onconfigurationchanged,我正在尝试使我的应用程序适应新的环境,但我遗漏了一些东西,我不知道它是什么。正如您将在下面看到的,NewsListFragment根据设备是处于纵向还是横向模式加载其布局,并且由于我没有手动处理配置更改,所以从纵向到横向会更改此类布局 预期行为:当布局为纵向时,仅显示列表。当布局为横向布局时,同时显示列表和网络视图 实际行为:当布局为纵向时,仅显示列表。但是,当布局为横向布局时,NewsListFragment将消失,这似乎没有任何意义,因为我已经为它设置了固定的宽度,并且它的高度设置为与父项匹

我正在尝试使我的应用程序适应新的环境,但我遗漏了一些东西,我不知道它是什么。正如您将在下面看到的,NewsListFragment根据设备是处于纵向还是横向模式加载其布局,并且由于我没有手动处理配置更改,所以从纵向到横向会更改此类布局

预期行为:当布局为纵向时,仅显示列表。当布局为横向布局时,同时显示列表和网络视图

实际行为:当布局为纵向时,仅显示列表。但是,当布局为横向布局时,NewsListFragment将消失,这似乎没有任何意义,因为我已经为它设置了固定的宽度,并且它的高度设置为与父项匹配

新闻列表片段:

公共类NewsListFragment扩展了ListFragment在RefreshListener上的实现{

private static PullToRefreshLayout mPullToRefreshLayout;
private NewsFragmentArrayAdapter listAdapter;
private NewsFeedProvider newsFeedProvider;
private NewsListFragmentListener mCallback;

/**
 * Called to do initial creation of a fragment.  This is called after
 * {@link #onAttach(android.app.Activity)} and before
 * {@link #onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle)}.
 * <p/>
 * <p>Note that this can be called while the fragment's activity is
 * still in the process of being created.  As such, you can not rely
 * on things like the activity's content view hierarchy being initialized
 * at this point.  If you want to do work once the activity itself is
 * created, see {@link #onActivityCreated(android.os.Bundle)}.
 *
 * @param savedInstanceState If the fragment is being re-created from
 *                           a previous saved state, this is the state.
 */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    if (listAdapter == null) {
        listAdapter = new NewsFragmentArrayAdapter(getActivity());
        setListAdapter(listAdapter);
    }
    if (newsFeedProvider == null) {
        newsFeedProvider = new NewsFeedProvider(getActivity());
    }
}

@Override
public void onListItemClick(ListView l, View v, int position, long id) {
    super.onListItemClick(l, v, position, id);
    getListView().setItemChecked(position, Boolean.TRUE);
    mCallback.onNewsArticleSelected(position);
}

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

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

    ((NewsReaderActivity) activity).onSectionAttached(
            new ArrayList<>(
                    Arrays.asList(
                            Utils.getStringArray(
                                    getActivity().getApplicationContext(),
                                    "navigation_drawer_items", new String[]{""})
                    )
            ).indexOf(Utils.getString(getActivity().getApplicationContext(), "title_section1",
                    "Home"))
    );
}

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

    listAdapter.updateShownNews();

    return ret;
}

/**
 * Attach to list view once the view hierarchy has been created.
 *
 * @param view
 * @param savedInstanceState
 */
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    // This is the View which is created by ListFragment
    ViewGroup viewGroup = (ViewGroup) view;

    // We need to create a PullToRefreshLayout manually
    mPullToRefreshLayout = new PullToRefreshLayout(viewGroup.getContext());

    Options.Builder optionsBuilder = Options.create();

    int retrieved = Utils.getInt(getActivity(), "feed_refresh_distance_percentage",
            R.integer.feed_refresh_distance_percentage);
    float scrollDistance = (float) retrieved / 100;
    optionsBuilder = optionsBuilder
            .scrollDistance(scrollDistance);

    optionsBuilder = optionsBuilder.headerTransformer(new TranslatableHeaderTransformer());

    // We can now setup the PullToRefreshLayout
    ActionBarPullToRefresh.from(getActivity())

            // We need to insert the PullToRefreshLayout into the Fragment's ViewGroup
            .insertLayoutInto(viewGroup)

                    // We need to mark the ListView and its empty view as pullable
                    // This is because they are not direct children of the ViewGroup
            .theseChildrenArePullable(getListView(), getListView().getEmptyView())
                    // Set the OnRefreshListener
            .listener(this).useViewDelegate(ImageView.class, new ViewDelegate() {
        @Override
        public boolean isReadyForPull(View view, float v, float v2) {
            return Boolean.TRUE;
        }
    }).options(optionsBuilder.build())
            // Finally commit the setup to our PullToRefreshLayout
            .setup(mPullToRefreshLayout);

    getListView().setChoiceMode(
            ListView.CHOICE_MODE_SINGLE);
}

@Override
public void onRefreshStarted(View view) {
    new AsyncTask<Void, Void, Void>() {
        /**
         * Override this method to perform a computation on a background thread. The
         * specified parameters are the parameters passed to {@link #execute}
         * by the caller of this task.
         * <p/>
         * This method can call {@link #publishProgress} to publish updates
         * on the UI thread.
         *
         * @param params The parameters of the task.
         * @return A result, defined by the subclass of this task.
         * @see #onPreExecute()
         * @see #onPostExecute
         * @see #publishProgress
         */
        @Override
        protected Void doInBackground(Void... params) {
            if (newsFeedProvider.requestFeedRefresh()) {
                listAdapter.updateShownNews();
            }
            return null;
        }

        /**
         * <p>Runs on the UI thread after {@link #doInBackground}. The
         * specified result is the value returned by {@link #doInBackground}.</p>
         * <p/>
         * <p>This method won't be invoked if the task was cancelled.</p>
         *
         * @param aVoid The result of the operation computed by {@link #doInBackground}.
         * @see #onPreExecute
         * @see #doInBackground
         * @see #onCancelled(Object)
         */
        @Override
        protected void onPostExecute(Void aVoid) {
            mPullToRefreshLayout.setRefreshComplete();
        }

        /**
         * <p>Applications should preferably override {@link #onCancelled(Object)}.
         * This method is invoked by the default implementation of
         * {@link #onCancelled(Object)}.</p>
         * <p/>
         * <p>Runs on the UI thread after {@link #cancel(boolean)} is invoked and
         * {@link #doInBackground(Object[])} has finished.</p>
         *
         * @see #onCancelled(Object)
         * @see #cancel(boolean)
         * @see #isCancelled()
         */
        @Override
        protected void onCancelled() {
            mPullToRefreshLayout.setRefreshComplete();
        }
    }.execute();
}


public interface NewsListFragmentListener {
    public void onNewsArticleSelected(int index);
}
}
values land/layouts.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="activity_news" type="layout">@layout/news_double_pane</item>
<bool name="has_two_panes">true</bool>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="activity_news" type="layout">@layout/news_single_pane</item>
<bool name="has_two_panes">true</bool>
</resources>

@布局/新闻双窗格
真的
values/layouts.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="activity_news" type="layout">@layout/news_double_pane</item>
<bool name="has_two_panes">true</bool>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="activity_news" type="layout">@layout/news_single_pane</item>
<bool name="has_two_panes">true</bool>
</resources>

@布局/新闻\u单个窗格
真的
news\u double\u pane.xml:

<?xml version="1.0" encoding="utf-8"?>

<android.support.v4.widget.DrawerLayout
android:id="@+id/drawer_layout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="@dimen/activity_vertical_margin"
android:layout_marginLeft="@dimen/activity_horizontal_margin"
android:layout_marginRight="@dimen/activity_horizontal_margin"
android:layout_marginTop="@dimen/activity_vertical_margin"
tools:context="org.jorge.lolin1.activities.MainActivity">
<fragment
    android:id="@+id/fragment_news"
    android:name="org.jorge.lolin1.frags.NewsListFragment"
    android:layout_width="@dimen/feed_item_length_percentage"
    android:layout_height="match_parent"/>
<fragment
    android:id="@+id/fragment_web_viewer"
    android:name="org.jorge.lolin1.frags.WebViewerFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/nothing_to_do_here"/>
<fragment
    android:id="@+id/navigation_drawer"
    android:name="org.jorge.lolin1.frags.NavigationDrawerFragment"
    android:layout_width="@dimen/navigation_drawer_width"
    android:layout_height="match_parent"
    android:layout_gravity="left"/>
</android.support.v4.widget.DrawerLayout>
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
android:id="@+id/drawer_layout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="org.jorge.lolin1.activities.MainActivity">

<fragment android:id="@+id/fragment_news"
          android:name="org.jorge.lolin1.frags.NewsListFragment"
          android:layout_width="match_parent"
          android:layout_height="match_parent"/>
<fragment
    android:id="@+id/navigation_drawer"
    android:name="org.jorge.lolin1.frags.NavigationDrawerFragment"
    android:layout_width="@dimen/navigation_drawer_width"
    android:layout_height="match_parent"
    android:layout_gravity="left"/>
</android.support.v4.widget.DrawerLayout>

news_single_pane.xml:

<?xml version="1.0" encoding="utf-8"?>

<android.support.v4.widget.DrawerLayout
android:id="@+id/drawer_layout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="@dimen/activity_vertical_margin"
android:layout_marginLeft="@dimen/activity_horizontal_margin"
android:layout_marginRight="@dimen/activity_horizontal_margin"
android:layout_marginTop="@dimen/activity_vertical_margin"
tools:context="org.jorge.lolin1.activities.MainActivity">
<fragment
    android:id="@+id/fragment_news"
    android:name="org.jorge.lolin1.frags.NewsListFragment"
    android:layout_width="@dimen/feed_item_length_percentage"
    android:layout_height="match_parent"/>
<fragment
    android:id="@+id/fragment_web_viewer"
    android:name="org.jorge.lolin1.frags.WebViewerFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/nothing_to_do_here"/>
<fragment
    android:id="@+id/navigation_drawer"
    android:name="org.jorge.lolin1.frags.NavigationDrawerFragment"
    android:layout_width="@dimen/navigation_drawer_width"
    android:layout_height="match_parent"
    android:layout_gravity="left"/>
</android.support.v4.widget.DrawerLayout>
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
android:id="@+id/drawer_layout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="org.jorge.lolin1.activities.MainActivity">

<fragment android:id="@+id/fragment_news"
          android:name="org.jorge.lolin1.frags.NewsListFragment"
          android:layout_width="match_parent"
          android:layout_height="match_parent"/>
<fragment
    android:id="@+id/navigation_drawer"
    android:name="org.jorge.lolin1.frags.NavigationDrawerFragment"
    android:layout_width="@dimen/navigation_drawer_width"
    android:layout_height="match_parent"
    android:layout_gravity="left"/>
</android.support.v4.widget.DrawerLayout>

设法解决了这个问题。结果证明这是一个非常简单的问题,其中一个问题表明您已经为今天编写了足够的代码:p

在问题中给出的代码中,android.support.v4.widget.DrawerLayout是所有片段(导航抽屉、列表和内容支架)的父级但是,由于它的行为,它允许内容支架浏览列表,完全覆盖列表。因此,解决方案很简单,只需将列表和内容支架移动到一个内部线性布局(例如)