0

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

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

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

新闻列表片段:

公共类 NewsListFragment 扩展 ListFragment 实现 OnRefreshListener {

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);
}
}

新闻阅读器活动:

public class NewsReaderActivity extends FragmentActivity implements
    NewsListFragment.NewsListFragmentListener,
    NavigationDrawerFragment.NavigationDrawerCallbacks {
private Boolean isDualPane = Boolean.FALSE;
private NewsListFragment NEWS_FRAGMENT;
private WebViewerFragment WEB_FRAGMENT;
private int lastSelectedNavDrawerItem = 0;
private NavigationDrawerFragment mNavigationDrawerFragment;
private CharSequence mTitle;

private void restoreActionBar() {
    ActionBar actionBar = getActionBar();
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
    actionBar.setDisplayShowTitleEnabled(true);
    actionBar.setTitle(mTitle);
}

/**
 * Called when an item in the navigation drawer is selected.
 *
 * @param position
 */
@Override
public void onNavigationDrawerItemSelected(int position) {
    if (position == lastSelectedNavDrawerItem) {
        //We don't want to perform a useless fragment reload
        return;
    }
    else {
        lastSelectedNavDrawerItem = position;
    }
    //TODO The rest of the stuff
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    if (!mNavigationDrawerFragment.isDrawerOpen()) {
        getMenuInflater().inflate(R.menu.standard, menu);
        restoreActionBar();
        return true;
    }
    return super.onCreateOptionsMenu(menu);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.action_settings:
            startActivity(new Intent(this, SettingsPreferenceActivity.class));
            break;
        default: //Up button
            return super.onOptionsItemSelected(item);
    }
    return true;
}

public void onSectionAttached(int number) {
    int shiftedPos = number + 1;
    mTitle = Utils.getString(this, "title_section" + shiftedPos, "");
    if (mTitle.toString().isEmpty()) {
        mTitle = getString(R.string.title_section1);
    }
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_news);

    FragmentManager fragmentManager = getFragmentManager();

    mNavigationDrawerFragment = (NavigationDrawerFragment)
            fragmentManager.findFragmentById(R.id.navigation_drawer);
    mTitle = getTitle();

    // Set up the drawer.
    mNavigationDrawerFragment.setUp(
            R.id.navigation_drawer,
            (DrawerLayout) findViewById(R.id.drawer_layout));

    NEWS_FRAGMENT =
            (NewsListFragment) getFragmentManager().findFragmentById(R.id.fragment_news);
    WEB_FRAGMENT =
            (WebViewerFragment) getFragmentManager().findFragmentById(R.id.fragment_web_viewer);

    View webView = findViewById(R.id.fragment_web_viewer);
    isDualPane = webView != null && webView.getVisibility() == View.VISIBLE;
    restoreState(savedInstanceState);
}

private void restoreState(Bundle savedInstanceState) {
    if (savedInstanceState != null) {
        int index = savedInstanceState.getInt("index", 0);
        NEWS_FRAGMENT.setSelection(index);
        onNewsArticleSelected(index);
    }
}


@Override
public void onNewsArticleSelected(int index) {
    showUrlInWebViewerFragment(index);
}

private void showUrlInWebViewerFragment(int index) {
    if (isDualPane) {
        WEB_FRAGMENT.loadUrl(SQLiteBridge.getSingleton().getNews().get(index).getLink());
    }
    else {
        Intent singleViewIntent = new Intent(this, WebViewerActivity.class);
        singleViewIntent.putExtra("index", index);
        startActivity(singleViewIntent);
    }
}
}

值土地/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>

值/layouts.xml:

<?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>

news_double_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>

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"
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>
4

1 回答 1

0

设法解决它。事实证明这是一个非常简单的问题,其中一个表明您今天已经编写了足够多的代码:P

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

<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2011 The Android Open Source Project

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
-->

<!-- BEGIN_INCLUDE(all) -->
<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/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"
        tools:layout="@layout/fragment_navigation_drawer"/>
    <LinearLayout 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">
        <fragment
            android:id="@+id/fragment_news"
            android:name="org.jorge.lolin1.frags.NewsListFragment"
            android:layout_width="@dimen/feed_item_width"
            android:layout_height="match_parent"
            tools:layout="@layout/fragment_news_feed"/>
        <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"
            tools:layout="@layout/fragment_web_viewer"/>
    </LinearLayout>
</android.support.v4.widget.DrawerLayout>
    <!-- END_INCLUDE(all) -->
于 2014-02-08T15:28:43.630 回答