2016-09-05 24 views
8

Tôi đã triển khai BottomSheet bằng cách sử dụng phương pháp DialogFragment. Tôi có một số TabLayoutViewPager trong số BottomSheet. Các ViewPager được lưu trữ 2 trang, mỗi trang thổi phồng một RecyclerView. Tab đầu tiên (Tab cà phê) RecyclerView cuộn tốt. Vấn đề tôi đang gặp bây giờ là ở mục 2 (tab Milk), cuộn không hoạt động. Bất kỳ ý tưởng làm thế nào tôi có thể sửa lỗi này? Cảm ơn!Di chuyển không hoạt động đối với nhiều RecyclerView trong BottomSheet

Bạn có thể kiểm tra với các dự án trình diễn tôi đã tạo ở đây: https://github.com/choongyouqi/bottomsheet '

enter image description here

+0

Im cá cược của mình không lạm phát một cách chính xác. Bạn có thiết lập cho ngành dọc không? – MNM

+0

Kiểm tra câu trả lời của tôi bên dưới không có bất kỳ thư viện bổ sung nào được sử dụng không phải là lỗi của chúng như được nêu trong các câu trả lời khác. –

+0

Có thể trùng lặp của [Android ViewPager với RecyclerView hoạt động không chính xác bên trong BottomSheet] (http://stackoverflow.com/questions/37715822/android-viewpager-with-recyclerview-works-incorrectly-inside-bottomsheet) – Vitaly

Trả lời

6

Như đã đề cập trong R. Zagórski, tôi đã mô tả lý do cho hành vi cuộn này here, tức là, BottomSheetBehavior chỉ hỗ trợ một con di chuyển. Tuy nhiên câu trả lời này không tập trung vào các hộp thoại Bottom Sheet.

Do đó - giống như R. Zagórski - tôi đã mở rộng library của riêng mình để khắc phục giới hạn này. Bắt đầu với 0.0.3 có hỗ trợ cho Hộp thoại dưới cùng! Bạn có thể tìm thấy thư viện và ứng dụng ví dụ ở đây: https://github.com/laenger/ViewPagerBottomSheet

Để sử dụng trong dự án của bạn, chỉ cần thêm url repo maven để build.gradle của bạn:

repositories { 
    maven { url "https://raw.github.com/laenger/maven-releases/master/releases" } 
} 

Thêm thư viện để các phụ thuộc:

dependencies { 
    compile "biz.laenger.android:vpbs:0.0.3" 
} 

Sử dụng ViewPagerBottomSheetDialogFragment làm siêu lớp cho Phân đoạn hộp thoại. Sau đó, thiết lập bất kỳ ViewPager bên trong xem nội dung:

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

sample implementation

3

Khi cố gắng để tìm kiếm các vấn đề trên StackOverflow tôi thấy this thread. Nó mô tả về lỗi (ít nhất đó là cách tôi nhìn vào nó), rằng BottomSheetBehaviour chỉ hoạt động cho con cuộn đầu tiên mà nó tìm thấy. Nó cũng đề xuất việc sử dụng CoordinatorLayout.Behavior khác nhau được đề xuất và xuất bản here.

Tuy nhiên, trường hợp của bạn hơi khác một chút. BottomSheetDialogFragment được sử dụng. Và đây là nơi giải pháp được cung cấp không hoạt động. Tuy nhiên, tôi đã cố gắng giải quyết vấn đề này. Đã xuất bản repository, nơi dự án của bạn đã được sửa đổi để hoạt động. Nó sử dụng ViewPagerBottomSheetBehavior từ thư viện được đề cập trước đó.

Về cơ bản, những thay đổi sau đây đã được thực hiện:

  1. StatisticFragment kéo dài ViewPagerBottomSheetDialogFragment và không BottomSheetDialogFragment
  2. Chức năng onCreateDialog trong StatisticsFragment được thay đổi:

    @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; 
    } 
    
  3. Chức năng sau đây được gọi về số ViewPager:

    BottomSheetUtils.setupViewPager(viewPager); 
    

Và đó là tất cả. Dự án hoạt động.

Sau đây là thực hiện đằng sau hậu trường:

BottomSheetDialogFragment chỉ có một phương pháp:

@Override 
public Dialog onCreateDialog(Bundle savedInstanceState) { 
    return new BottomSheetDialog(getContext(), getTheme()); 
} 

BottomSheetDialog được trả về. Tuy nhiên, nó có hành vi được xác định tĩnh được đặt thành BottomSheetBehavior. Điều cần thiết là ghi đè ViewPagerBottomSheetDialogFragment để trả lại ViewPagerBottomSheetDialog trong đó CoordinatorLayout.Behavior được đặt thành ViewPagerBottomSheetBehavior. Ngoài ra, cần có BottomSheet tùy chỉnh để được ghi đè để tùy chỉnh theo số ViewPagerBottomSheetBehavior.

+0

nó không hoạt động cho tôi: (Tôi chỉ có thể cuộn các mục của mục viewpager đầu tiên .Trong cùng một vấn đề với thư viện này quá –

0

Bạn không cần phải kéo dài StatisticFragment như ViewPagerBottomSheetDialogFragment hoặc không cần phải sử dụng bất kỳ thư viện cho điều đó.

Đó là bạn mã tôi đã chỉ cần thực hiện một số thay đổi trong Static Fragment của bạn liên quan đến View Pager.

Đây là Statistic Fragment trong đó tôi đã thực hiện thay đổi.

Không có bất kỳ lỗi nào được nêu trong tất cả các câu trả lời ở trên.

Thay thế mã này bằng Static fragment cũ của bạn mà không có bất kỳ thay đổi nào khác mà nó sẽ cung cấp cho bạn đầu ra mong muốn.

Tôi vừa thực hiện các thay đổi với chỉ View Pager của bạn và làm cho nó hoạt động như bạn muốn. sử dụng phương thức OnPageChangeListener chỉ nhận được chế độ xem đó.

Thống kê 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"; 
      } 

     } 
    } 

Nó Xong.

enter image description here

+1

nó sẽ mất trạng thái cuộn từ trang trước vì bạn chỉ đang tạo lại bộ điều hợp và đóng lại tablayout mỗi khi người dùng vuốt sang trái/phải Không chỉ nó bẩn và đắt tiền, nó gây ra nhấp nháy trong khi trang được chuyển tiếp.Tôi đang thực sự tìm kiếm một giải pháp mà bạn chuyển sự kiện/sự kiện 'fling' đến trang đang hoạt động của người xem. –

0

bạn có thể sử dụng 2 RecyclerView trong CoordinatorLayout.

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

kiểm tra bài này link

Các vấn đề liên quan