Android 片段适配UI(典型的双片段新闻阅读器)-在双窗格模式下缺少第一个片段
我正在尝试使我的应用程序适应新的环境,但我遗漏了一些东西,我不知道它是什么。正如您将在下面看到的,NewsListFragment根据设备是处于纵向还是横向模式加载其布局,并且由于我没有手动处理配置更改,所以从纵向到横向会更改此类布局 预期行为:当布局为纵向时,仅显示列表。当布局为横向布局时,同时显示列表和网络视图 实际行为:当布局为纵向时,仅显示列表。但是,当布局为横向布局时,NewsListFragment将消失,这似乎没有任何意义,因为我已经为它设置了固定的宽度,并且它的高度设置为与父项匹配 新闻列表片段: 公共类NewsListFragment扩展了ListFragment在RefreshListener上的实现{Android 片段适配UI(典型的双片段新闻阅读器)-在双窗格模式下缺少第一个片段,android,android-fragments,onconfigurationchanged,Android,Android Fragments,Onconfigurationchanged,我正在尝试使我的应用程序适应新的环境,但我遗漏了一些东西,我不知道它是什么。正如您将在下面看到的,NewsListFragment根据设备是处于纵向还是横向模式加载其布局,并且由于我没有手动处理配置更改,所以从纵向到横向会更改此类布局 预期行为:当布局为纵向时,仅显示列表。当布局为横向布局时,同时显示列表和网络视图 实际行为:当布局为纵向时,仅显示列表。但是,当布局为横向布局时,NewsListFragment将消失,这似乎没有任何意义,因为我已经为它设置了固定的宽度,并且它的高度设置为与父项匹
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是所有片段(导航抽屉、列表和内容支架)的父级但是,由于它的行为,它允许内容支架浏览列表,完全覆盖列表。因此,解决方案很简单,只需将列表和内容支架移动到一个内部线性布局(例如)