BottomSheet
アプローチを使用してDialogFragment
を実装しました。 TabLayout
にViewPager
とBottomSheet
があります。 ViewPager
は2ページをホストしており、それぞれがRecyclerView
を膨らませています。最初の([コーヒー]タブ)RecyclerView
は正常にスクロールします。私が今持っている問題は、2番目(ミルクタブ)ではスクロールが機能しないことです。どうすればこれを修正できますか?ありがとう!
ここで作成したデモプロジェクトでテストできます: https://github.com/choongyouqi/bottomsheet `
R.Zagórskiが述べたように、このスクロール動作の理由を説明しました here 、つまり、BottomSheetBehavior
は1つのスクロール子のみをサポートします。ただし、この回答はボトムシートダイアログに焦点を当てていませんでした。
したがって、R。ザゴルスキーと同様に、この制限を克服する独自の library を拡張しました。 0.0.3以降、ボトムシートダイアログがサポートされます!ライブラリとサンプルアプリはこちらからご覧いただけます: https://github.com/laenger/ViewPagerBottomSheet
プロジェクトで使用するには、mavenリポジトリのURLをbuild.gradleに追加するだけです。
repositories {
maven { url "https://raw.github.com/laenger/maven-releases/master/releases" }
}
ライブラリを依存関係に追加します。
dependencies {
compile "biz.laenger.Android:vpbs:0.0.3"
}
ViewPagerBottomSheetDialogFragment
をダイアログフラグメントのスーパークラスとして使用します。次に、コンテンツビュー内にViewPagerを設定します。
public class DialogFragment extends ViewPagerBottomSheetDialogFragment {
@Override
public void setupDialog(Dialog dialog, int style) {
super.setupDialog(dialog, style);
final View contentView = View.inflate(getContext(), R.layout.dialog_bottom_sheet, null);
final ViewPager viewPager = (ViewPager) contentView.findViewById(R.id.viewpager);
// ...
BottomSheetUtils.setupViewPager(viewPager);
dialog.setContentView(contentView);
}
}
StackOverflowで問題を検索しようとしたところ、 this thread が見つかりました。それは、バグについて(少なくとも私がそれを見る方法です)、BottomSheetBehaviour
は最初に見つかったスクロール可能な子に対してのみ機能することを示しています。また、提案され公開されているさまざまなCoordinatorLayout.Behavior
here の使用法も提案しています。
ただし、ケースは少し異なります。 BottomSheetDialogFragment
が使用されます。そして、これは提供されたソリューションが機能しない場所です。しかし、なんとかこの問題を克服することができました。公開 リポジトリ 、プロジェクトが機能するように変更された場所。前述のライブラリのViewPagerBottomSheetBehavior
を使用します。
基本的に、次の変更が行われました。
StatisticFragment
はViewPagerBottomSheetDialogFragment
ではなくBottomSheetDialogFragment
を拡張しますStatisticsFragment
のonCreateDialog関数が変更されました:
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
ViewPagerBottomSheetDialog dialog = (ViewPagerBottomSheetDialog) super.onCreateDialog(savedInstanceState);
View rootView = View.inflate(getContext(), R.layout.sheet_main, null);
viewPager = (ViewPager) rootView.findViewById(R.id.viewpager);
tabLayout = (TabLayout) rootView.findViewById(R.id.tabs);
dialog.setContentView(rootView);
mBehavior = ViewPagerBottomSheetBehavior.from((View) rootView.getParent());
mBehavior.setPeekHeight(400);
if (viewPager != null && tabLayout != null) {
initViewPager();
}
return dialog;
}
次の関数がViewPager
で呼び出されます:
BottomSheetUtils.setupViewPager(viewPager);
そして、それがすべてです。プロジェクトは機能します。
以下は裏で行われます:
BottomSheetDialogFragment
には1つのメソッドしかありません:
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new BottomSheetDialog(getContext(), getTheme());
}
そこでBottomSheetDialog
が返されます。ただし、静的に定義された動作はBottomSheetBehavior
に設定されています。 ViewPagerBottomSheetDialogFragment
をオーバーライドしてViewPagerBottomSheetDialog
を返すことで、CoordinatorLayout.Behavior
がViewPagerBottomSheetBehavior
に設定されました。また、BottomSheet
に慣れるには、カスタムViewPagerBottomSheetBehavior
をオーバーライドする必要がありました。
coordinatorLayoutで2 RecyclerViewを使用できます。
<Android.support.design.widget.CoordinatorLayout
Android:id="@+id/mainBottomSheet"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:background="@color/white">
<Android.support.v7.widget.RecyclerView
Android:id="@+id/recyclerViewRight"
Android:layout_width="match_parent"
Android:layout_height="match_parent" />
<Android.support.v7.widget.RecyclerView
Android:id="@+id/recyclerViewLeft"
Android:layout_width="200dp"
Android:layout_height="match_parent" />
</Android.support.design.widget.CoordinatorLayout>
この投稿をチェック リンク
StatisticFragment
をViewPagerBottomSheetDialogFragment
として拡張する必要はなく、そのためにライブラリを使用する必要もありません。
Static Fragment
に関連するView Pager.
に変更を加えたばかりのコードです
これが私が変更を加えたStatistic Fragment
です。
上記のすべての回答に記載されているようなバグはありません。
このコードを古いStatic fragment
で置き換えてください。望ましい出力が得られる他の変更はありません。
View Pager
のみを変更し、ご希望どおりに機能させることができました。 OnPageChangeListener
メソッドを使用すると、そのビューを取得できます。
Statistic Fragment.Java
public class StatisticFragment extends BottomSheetDialogFragment {
private BottomSheetBehavior mBehavior;
private TabLayout tabLayout;
private ViewPager viewPager;
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
BottomSheetDialog dialog = (BottomSheetDialog) super.onCreateDialog(savedInstanceState);
View rootView = View.inflate(getContext(), R.layout.sheet_main, null);
viewPager = (ViewPager) rootView.findViewById(R.id.viewpager);
tabLayout = (TabLayout) rootView.findViewById(R.id.tabs);
if (viewPager != null && tabLayout != null) {
initViewPager();
}
final ViewPager.OnPageChangeListener pageChangeListener = new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int arg0) {
// TODO Auto-generated method stub
View view = viewPager.findViewWithTag(arg0);
if (view == null) {
return;
}
CustomPagerAdapter adapter = new CustomPagerAdapter(getContext());
viewPager.setAdapter(adapter);
viewPager.setOffscreenPageLimit(10);
tabLayout.setupWithViewPager(viewPager);
}
@Override
public void onPageScrollStateChanged(int state) {
}
};
viewPager.addOnPageChangeListener(pageChangeListener);
viewPager.post(new Runnable() {
@Override
public void run() {
pageChangeListener.onPageSelected(viewPager.getCurrentItem());
}
});
dialog.setContentView(rootView);
mBehavior = BottomSheetBehavior.from((View) rootView.getParent());
return dialog;
}
private void initViewPager() {
CustomPagerAdapter adapter = new CustomPagerAdapter(getContext());
viewPager.setAdapter(adapter);
viewPager.setOffscreenPageLimit(10);
tabLayout.setupWithViewPager(viewPager);
}
@Override
public void onStart() {
super.onStart();
//mBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
//mBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
}
public class ServiceVideHolder extends RecyclerView.ViewHolder {
protected ViewGroup mItemView;
protected TextView mNameView;
protected TextView mCodeView;
public ServiceVideHolder(View v) {
super(v);
//rootView = v;
mItemView = (ViewGroup) v.findViewById(R.id.item);
mNameView = (TextView) v.findViewById(R.id.main_text);
mCodeView = (TextView) v.findViewById(R.id.sub_text);
}
}
public class ItemViewHolder extends RecyclerView.ViewHolder {
protected TextView mMainText;
protected TextView mSubText;
public ItemViewHolder(View v) {
super(v);
mMainText = (TextView) v.findViewById(R.id.main_text);
mSubText = (TextView) v.findViewById(R.id.sub_text);
}
}
public class ItemAdapter extends RecyclerView.Adapter<ItemViewHolder> {
private List<Item> items;
public ItemAdapter(List<Item> items) {
this.items = items;
}
@Override
public ItemViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item, viewGroup, false);
return new ItemViewHolder(view);
}
@Override
public void onBindViewHolder(final ItemViewHolder viewHolder, final int position) {
final Item item = items.get(position);
viewHolder.mMainText.setText(item.name);
viewHolder.mSubText.setText(item.value);
viewHolder.mMainText.setTextColor(ResourcesCompat.getColor(getResources(), position % 2 == 0 ? R.color.md_red_500 : R.color.md_blue_500, null));
}
@Override
public int getItemCount() {
return items.size();
}
}
class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
@Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
@Override
public int getCount() {
return mFragmentList.size();
}
public void addFrag(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
@Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
public class CustomPagerAdapter extends PagerAdapter {
private Context mContext;
public CustomPagerAdapter(Context context) {
mContext = context;
}
@Override
public Object instantiateItem(ViewGroup collection, int position) {
//CustomPagerEnum customPagerEnum = CustomPagerEnum.values()[position];
LayoutInflater inflater = LayoutInflater.from(mContext);
ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.adapter, collection, false);
rootView.setTag(position);
Toast.makeText(mContext, "Inside Instanciate Item", Toast.LENGTH_SHORT).show();
//View rootView = View.inflate(getContext(), R.layout.adapter, null);
final RecyclerView mRecyclerView = (RecyclerView) rootView.findViewById(R.id.recycler_view);
ArrayList<Item> items = new ArrayList<>();
if (position == 0) {
items.add(new Item("Coffee 1", "1"));
items.add(new Item("Coffee 2", "2"));
items.add(new Item("Coffee 3", "3"));
items.add(new Item("Coffee 4", "4"));
items.add(new Item("Coffee 5", "5"));
items.add(new Item("Coffee 6", "6"));
items.add(new Item("Coffee 7", "7"));
items.add(new Item("Coffee 8", "8"));
items.add(new Item("Coffee 9", "9"));
items.add(new Item("Coffee 10", "10"));
} else {
items.add(new Item("Milk 1", "1"));
items.add(new Item("Milk 2", "2"));
items.add(new Item("Milk 3", "3"));
items.add(new Item("Milk 4", "4"));
items.add(new Item("Milk 5", "5"));
items.add(new Item("Milk 6", "6"));
items.add(new Item("Milk 7", "7"));
items.add(new Item("Milk 8", "8"));
items.add(new Item("Milk 9", "9"));
items.add(new Item("Milk 10", "10"));
}
final ItemAdapter mAdapter = new ItemAdapter(items);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false));
mRecyclerView.setNestedScrollingEnabled(false);
mRecyclerView.setAdapter(mAdapter);
Paint paint = new Paint();
Paint.setStrokeWidth(1);
Paint.setColor(ResourcesCompat.getColor(getResources(), R.color.md_grey_500, null));
Paint.setAntiAlias(true);
Paint.setPathEffect(new DashPathEffect(new float[]{25.0f, 25.0f}, 0));
mRecyclerView.addItemDecoration(new HorizontalDividerItemDecoration.Builder(getActivity()).showLastDivider().Paint(paint).build()); //.marginResId(R.dimen.leftmargin, R.dimen.rightmargin)
collection.addView(rootView);
return rootView;
}
@Override
public void destroyItem(ViewGroup collection, int position, Object view) {
collection.removeView((View) view);
}
@Override
public int getCount() {
return 2;
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
@Override
public CharSequence getPageTitle(int position) {
//CustomPagerEnum customPagerEnum = CustomPagerEnum.values()[position];
return position == 0 ? "Coffee" : "Milk";
}
}
}
完了です