实现Fragment实例化会产生相反的效果

时间:2015-07-04 13:24:22

标签: android web-services android-fragments tabs rotation

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中。所有应用程序加载,都来自新的开始:

  1. 旋转设备。所有3个选项卡都将加载其数据。当前选项卡,以及选择的其他选项卡(滑动到它们)。
  2. 从第一个标签中,单击标签3,然后返回标签1.标签1数据将加载。标签2不会加载。选项卡3将加载选择。要加载Tab 2数据,我需要旋转设备
  3. 代码

    片段

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

    BaseActivity

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

1 个答案:

答案 0 :(得分:1)

每当异步任务完成其工作时,您需要更新适配器并通知其项目有更改。

更新适配器视图需要在主线程中,因此请在您的任务中添加以下方法:

@Override
protected void onPostExecute(Void nothing) {
    adapter.notifyDataSetChanged();
}