【发布时间】:2017-12-05 00:23:14
【问题描述】:
我在一个简单的示例应用程序中设置了一个 ViewPager。我有一个静态片段实现为内部类,其中包含 RecylerView。我想根据我所在的选项卡更改 RecyclerView 的 LayoutManager。我的实现如下所示。这对我不起作用。当我加载这个 ViewPager 时,它从第一个位置开始,但有一个交错布局(应该是第三个位置)。当我滑动到第二个位置时,它仍然是交错布局,没有任何改变,因为我的 PagerAdapter 的 getItem() 方法从未被调用过。当我切换到第三个位置时,确实调用了 getItem() 并重新加载了 RecylerView,但是它仍然具有交错布局(这是它实际上应该具有交错布局的地方)。
在阅读了一些 ViewPagers 之后,我意识到如果 PagerAdapter 确定可以重用该片段,它就会重用该片段。我认为这就是这里正在发生的事情。有什么办法可以防止这种情况发生吗?我可以让我的 LayoutManager 在只使用一个片段的同时切换每个选项卡吗?本质上,我希望它为每个选项卡实例化一个新的 Fragment。
public class TabbedActivity extends AppCompatActivity {
/**
* The {@link android.support.v4.view.PagerAdapter} that will provide
* fragments for each of the sections. We use a
* {@link FragmentPagerAdapter} derivative, which will keep every
* loaded fragment in memory. If this becomes too memory intensive, it
* may be best to switch to a
* {@link android.support.v4.app.FragmentStatePagerAdapter}.
*/
private SectionsPagerAdapter mSectionsPagerAdapter;
/**
* The {@link ViewPager} that will host the section contents.
*/
private ViewPager mViewPager;
public static Intent newIntent(Context packageContext){
Intent intent = new Intent(packageContext, TabbedActivity.class);
return intent;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tabbed);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Create the adapter that will return a fragment for each of the three
// primary sections of the activity.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_tabbed, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public static class RecyclerFragment extends Fragment {
private static final String ARG_LAYOUT_TYPE = "layout-type";
private int layoutType = 0;
RecyclerView recyclerView;
public ArrayList<AndroidVersion> data;
public DataAdapter adapter;
public static final int FRAGMENT_LINEAR = 0;
public static final int FRAGMENT_GRID = 1;
public static final int FRAGMENT_STAG_GRID = 2;
public static RecyclerFragment newInstance(int layoutType) {
Timber.d("newInstance() called with int: " + layoutType);
RecyclerFragment fragment = new RecyclerFragment();
Bundle args = new Bundle();
args.putInt(ARG_LAYOUT_TYPE, layoutType);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
if(getArguments() != null){
layoutType = getArguments().getInt(ARG_LAYOUT_TYPE);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
View rootView = inflater.inflate(R.layout.fragment_linear, container, false);
Button button = (Button) rootView.findViewById(R.id.view_pager_button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent mainActivityIntent = MainActivity.newIntent(getActivity().getApplicationContext());
startActivity(mainActivityIntent);
}
});
recyclerView = (RecyclerView) rootView.findViewById(R.id.card_recyler_view_pager);
//recyclerView.setHasFixedSize(true);
// Check to see what the layout type should be and create the necessary LayoutManager
switch(layoutType){
case FRAGMENT_LINEAR:
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false);
recyclerView.setLayoutManager(layoutManager);
case FRAGMENT_GRID:
GridLayoutManager gridLayoutManager = new GridLayoutManager(getActivity(), 3);
recyclerView.setLayoutManager(gridLayoutManager);
case FRAGMENT_STAG_GRID:
StaggeredGridLayoutManager staggeredGridLayoutManager = new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL);
recyclerView.setLayoutManager(staggeredGridLayoutManager);
}
loadJSON();
return rootView;
}
private void loadJSON() {
Retrofit retrofit = MainActivity.getRestAdapter();
RequestInterface request = retrofit.create(RequestInterface.class);
Call<JSONResponse> call = request.getJSON();
call.enqueue(new Callback<JSONResponse>() {
@Override
public void onResponse(Call<JSONResponse> call, Response<JSONResponse> response) {
JSONResponse jsonResponse = response.body();
data = new ArrayList<>(Arrays.asList(jsonResponse.getAndroid()));
adapter = new DataAdapter(data);
recyclerView.setAdapter(adapter);
}
@Override
public void onFailure(Call<JSONResponse> call, Throwable t) {
Log.d("Error", t.getMessage());
}
});
}
}
/**
* A {@link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
Timber.d("getItem called, position: " + position);
return RecyclerFragment.newInstance(position);
}
@Override
public int getCount() {
// Show 3 total pages.
return 3;
}
@Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "Linear";
case 1:
return "Grid";
case 2:
return "Staggered";
}
return null;
}
}
}
【问题讨论】:
-
更新
ViewPager#addOnPageChangeListener -
我不能直接从 ViewPager 活动更新片段,因为它是一个静态片段。我尝试从 addOnPageChangeListener() 调用内部调用
sectionsPagerAdapter.getItem(position),但这并没有改变任何东西。
标签: android android-fragments android-viewpager static-classes