I have implemented my fragment to the Android's best practice of using newInstance
with parameters.它有效,但是带有阴影。
带有参数修复的newInstance
问题是,Android将在屏幕旋转时调用默认的no-args构造函数。这意味着您将丢失旋转数据。 newInstance
允许您setArguments
旋转时保留。
使用overloaded constructor
表示您的数据将在旋转设备之前第一次正确显示。 newInstance
将允许您的片段在第一次旋转时正确工作。
问题
但是,似乎我的作用相反。我的代码可以在轮换上正常工作,但在第一次尝试时却无法正常工作。如果我将构造函数与参数一起使用,则会产生相同的效果。
在应用程序加载时,它将在Tablayout
中显示我的标签(3),但我的RecyclerView
都没有其中的项目。
这是我如何最快地将数据加载到RecyclerView
中的方法。全部来自应用程序负载,并且都是全新的:
旋转设备。所有3个标签页都会加载其数据。现在的当前选项卡,以及选中的其他选项卡(滑至它们)。
在第一个选项卡上,单击选项卡3,然后返回到选项卡1。将加载选项卡1的数据。标签2不会加载。选项卡3将在选择时加载。要加载Tab 2数据,我需要旋转设备
码
分段
public class MovieListFragment extends Fragment implements OnItemClickListener {
MovieListAdapter adapter;
WebAPI webAPI; // Advanced Enum
private static final String API_STRING = "api";
public MovieListFragment() {}
public static MovieListFragment newInstance(WebAPI API) {
MovieListFragment fragment = new MovieListFragment();
Bundle args = new Bundle();
args.putSerializable(API_STRING, API);
fragment.setArguments(args);
// if (API != null) fragment.webAPI = API;
return fragment;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_movies_list, container, false);
webAPI = (WebAPI) getArguments().getSerializable(API_STRING);
GetMoviesAsync getMovies = new GetMoviesAsync();
getMovies.execute();
adapter = new MovieListAdapter(getActivity(), webAPI, this);
RecyclerView movieListView;
movieListView = (RecyclerView) rootView.findViewById(R.id.movie_list);
movieListView.setAdapter(adapter);
movieListView.setLayoutManager(
new GridLayoutManager( // Changes number of columns based on form-factor and orientation
getActivity(),
getResources().getInteger(R.integer.columns)));
return rootView;
}
@Override
public void onClick(View v, int position) {
startActivity(new Intent(this.getActivity(), SecondaryActivity.class)); // TODO pass data to second activity
}
// ASYNC_TASK
public class GetMoviesAsync extends AsyncTask<Void, Void, Void> {
// CALLBACK
private final Handler.Callback getMoviesFromJSON = new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
// Take the JSON (msg) and convert it to a Java object (Movie)
Movie movie = new Movie(title, uri);
webAPI.addMovie(movie);
}
} catch (JSONException e) { return false; }
return true;
}
};
@Override
protected Void doInBackground(Void... params) {
try {
// This will get the JSON from the webservice, and will use the CallBack to assign the List of movies.
new WebService(webAPI.getUri()).acquireDataWithCallback(getMoviesFromJSON);
} catch (JSONException e) { e.printStackTrace(); }
return null;
}
}
}
基础活动
public abstract class BaseSearchTabbedActivity extends AppCompatActivity
implements SearchView.OnQueryTextListener {
EnumSet<WebAPI> tabs;
...
public void setTabs(EnumSet<WebAPI> tabs) { this.tabs = tabs; }
void initializeToolbar() { // Called in Activity's OnCreate
// Setup the toolbar
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Initialize all components. Tabs, Pager, and Adapter
tabLayout = (TabLayout) findViewById(R.id.tabs);
viewPager = (ViewPager) findViewById(R.id.pager);
adapter = new ViewPagerFragmentAdapter(getSupportFragmentManager());
// Add the tabs
collectTabValues(); // Set tabs from Activity
addFragments(tabs);
// Bind the adapter to the tabs
viewPager.setAdapter(adapter);
tabLayout.setupWithViewPager(viewPager);
}
private void addFragments(EnumSet<WebAPI> tabs) {
for (WebAPI tab : tabs) {
adapter.addFragment(MovieListFragment.newInstance(tab), tab);
}
}
最佳答案
每当异步任务完成其工作时,您都需要更新适配器并通知其项有更改。
更新适配器视图需要在主线程中,因此请在任务中添加以下方法:
@Override
protected void onPostExecute(Void nothing) {
adapter.notifyDataSetChanged();
}