2017-04-05 71 views
2

我使用Vertical RecyclerView中的Horizo​​ntal RecyclerView开发一个片段(如Google Play Store)。RecyclerView在RecyclerView parent.notifyDataSetChanged儿童的松动位置RecyclerView

当我从父RecyclerView通知DataSetChanged,子RecyclerView失去了位置,因为setAdapter是在onBindViewHolder调用,我认为。另外,当我滚动到第一个水平recyclerview中的第五个位置,如果我向下滚动并回来,我松开第五个位置。

我尝试使用RecyclerView.scrollToPosition()但不起作用。

因此,我认为我有两个解决方案:

  • 的方式(通过一种方法或设置),以保持我的孩子回收视图的位置。 (BEST SOLUTION)

  • 一种手动设置recyclerview位置到刷新前的位置的方法。 (ELSE SOLUTION)

这里我父适配器:

public class ProfilesCardViewListAdapter extends RecyclerView.Adapter<ProfilesCardViewListAdapter.ItemRowHolder> { 
    private ArrayList<AidodysProfile> sectionsList; 
    private Context context; 
    private boolean[] isShown; 
    private ProfileCardViewItemAdapter itemAdapters[]; 

    public ProfilesCardViewListAdapter(ArrayList<AidodysProfile> sectionsList, Context context) { 

     this.sectionsList = sectionsList; 
     this.context = context; 
     this.isShown = new boolean[sectionsList.size()]; 
     this.itemAdapters = new ProfileCardViewItemAdapter[sectionsList.size()]; 
     for (int i = 0; i < sectionsList.size(); i++) { 
      this.isShown[i] = true; 
      this.itemAdapters[i] = new ProfileCardViewItemAdapter(sectionsList.get(i).getProfiles(), context, this); 
     } 
    } 

    @Override 
    public ItemRowHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_card_view_horizontal, null); 
     final ItemRowHolder rowHolder = new ItemRowHolder(view); 

     return rowHolder; 
    } 

    @Override 
    public void onBindViewHolder(final ItemRowHolder holder, final int position) { 
     String sectionName = sectionsList.get(position).getName(); 

     AidodysProfile[] sectionItems = sectionsList.get(position).getProfiles(); 

     holder.sectionTitle.setTextSize(context.getResources().getDimension(R.dimen.text_size_profileslist_section_title)); 
     holder.sectionButton.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       showHideSection(holder, position); 
      } 
     }); 

     if (isShown[position]) { 
      holder.itemRecyclerView.setVisibility(View.VISIBLE); 
      holder.sectionButton.setText(context.getString(R.string.action_profiles_section_hide)); 
     } else { 
      holder.itemRecyclerView.setVisibility(View.GONE); 
      holder.sectionButton.setText(context.getText(R.string.action_profiles_section_show)); 
     } 

     if (!sectionsList.get(position).isLeaf()) { // FOLDER 
      if (sectionName.equals("")) { 
       holder.sectionTitle.setVisibility(View.GONE); 
       holder.sectionButton.setVisibility(View.GONE); 
      } else { 
       holder.sectionTitle.setVisibility(View.VISIBLE); 
       holder.sectionButton.setVisibility(View.VISIBLE); 
      } 
      holder.sectionTitle.setText(sectionName); 
     } else { // PROFILE 
      return; 
     } 

     holder.itemRecyclerView.setHasFixedSize(true); 
     holder.itemRecyclerView.setLayoutManager(new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)); 
     holder.itemRecyclerView.setAdapter(itemAdapters[position]); 

    } 

    private void showHideSection(ItemRowHolder holder, int position) { 
     if (holder.itemRecyclerView.getVisibility() == View.VISIBLE) { 
      isShown[position] = false; 
      holder.itemRecyclerView.setVisibility(View.GONE); 
      holder.sectionButton.setText(context.getText(R.string.action_profiles_section_show)); 
     } else { 
      isShown[position] = true; 
      holder.itemRecyclerView.setVisibility(View.VISIBLE); 
      holder.sectionButton.setText(context.getString(R.string.action_profiles_section_hide)); 
     } 
    } 

    @Override 
    public int getItemCount() { 
     return (sectionsList != null ? sectionsList.size() : 0); 
    } 

    public class ItemRowHolder extends RecyclerView.ViewHolder { 

     protected TextView sectionTitle; 
     protected RecyclerView itemRecyclerView; 
     protected Button sectionButton; 

     public ItemRowHolder(View view) { 
      super(view); 
      this.sectionTitle = (TextView) view.findViewById(R.id.section_title); 
      this.itemRecyclerView = (RecyclerView) view.findViewById(R.id.item_recycler_view); 
      this.sectionButton = (Button) view.findViewById(R.id.section_button); 
     } 

    } 
} 

儿童适配器:

class ProfileCardViewItemAdapter extends RecyclerView.Adapter<ProfileCardViewItemAdapter.SingleItemRowHolder> { 
    private AidodysProfile[] itemsList; 
    private CurrentUser currentUser; 
    private Context context; 
    private int selectedPos = -1; 
    private ProfilesCardViewListAdapter parent; 

    public ProfileCardViewItemAdapter(AidodysProfile[] itemsList, Context context, ProfilesCardViewListAdapter parent) { 
     this.itemsList = itemsList; 
     this.context = context; 
     this.parent = parent; 
     this.currentUser = CurrentUser.getInstance(context); 
    } 

    @Override 
    public SingleItemRowHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_card_view_horizontal, null); 
     SingleItemRowHolder rowHolder = new SingleItemRowHolder(view); 
     return (rowHolder); 
    } 

    @Override 
    public void onBindViewHolder(final SingleItemRowHolder holder, final int position) { 
     AidodysProfile profile = itemsList[position]; 

     holder.itemCardView.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       selectProfile(holder, position); 
      } 
     }); 

     if (profile.equals(currentUser.getProfile())) { 
      selectedPos = position; 
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 
       holder.itemCardView.setCardBackgroundColor(context.getColor(R.color.aidodysRed)); 
      } else { 
       holder.itemCardView.setCardBackgroundColor(context.getResources().getColor(R.color.aidodysRed)); 
      } 
     } else { 
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 
       holder.itemCardView.setCardBackgroundColor(context.getColor(R.color.white)); 
      } else { 
       holder.itemCardView.setCardBackgroundColor(context.getResources().getColor(R.color.white)); 
      } 
     } 

     holder.itemTitle.setText(profile.getName()); 

     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 
      holder.itemPicture.setImageDrawable(context.getDrawable(R.drawable.ic_sheet_smile_black_48dp)); 
      holder.button1.setImageDrawable(context.getDrawable(R.drawable.ic_edit_black_24dp)); 
      holder.button2.setImageDrawable(context.getDrawable(R.drawable.ic_look_profile)); 
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 
       holder.itemTitle.setTextAppearance(R.style.Aidodys_Text_ProfilesList_Item); 
       holder.itemPicture.setColorFilter(context.getColor(R.color.white)); 
       holder.topParts.setBackgroundColor(context.getColor(R.color.aidodysRed)); 
      } else { 
       holder.itemTitle.setTextColor(context.getResources().getColor(R.color.white)); 
       holder.itemTitle.setTextSize(context.getResources().getDimension(R.dimen.text_size_profileslist_item)); 
       holder.itemPicture.setColorFilter(context.getResources().getColor(R.color.white)); 
       holder.topParts.setBackgroundColor(context.getResources().getColor(R.color.aidodysRed)); 
      } 
     } else { 
      holder.button1.setImageDrawable(context.getResources().getDrawable(R.drawable.ic_edit_black_24dp)); 
      holder.button2.setImageDrawable(context.getResources().getDrawable(R.drawable.ic_look_profile)); 
      holder.itemTitle.setTextColor(context.getResources().getColor(R.color.white)); 
      holder.itemTitle.setTextSize(context.getResources().getDimension(R.dimen.text_size_profileslist_item)); 
      holder.itemPicture.setImageDrawable(context.getResources().getDrawable(R.drawable.ic_sheet_smile_black_48dp)); 
      holder.itemPicture.setColorFilter(context.getResources().getColor(R.color.white)); 
      holder.topParts.setBackgroundColor(context.getResources().getColor(R.color.aidodysRed)); 
     } 
    } 

    private void selectProfile(SingleItemRowHolder holder, int position) { 
     SharedPreferences.Editor editor = context.getSharedPreferences("Aidodys", 0).edit(); 
     editor.putString("profile", new Gson().toJson(itemsList[position])); 
     editor.apply(); 
     currentUser.setProfile(itemsList[position]); 
     parent.notifyDataSetChanged(); 
     notifyDataSetChanged(); 
     ((RecyclerView)holder.itemCardView.getParent()).scrollToPosition(position); 
     selectedPos = position; 
    } 

    @Override 
    public int getItemCount() { 
     return (itemsList != null ? itemsList.length : 0); 
    } 

    public class SingleItemRowHolder extends RecyclerView.ViewHolder { 

     protected TextView itemTitle; 
     protected ImageView itemPicture; 
     protected CardView itemCardView; 
     protected ImageView button1; 
     protected ImageView button2; 
     protected LinearLayout topParts; 

     public SingleItemRowHolder(View view) { 
      super(view); 

      this.itemTitle = (TextView)view.findViewById(R.id.item_title); 
      this.itemPicture = (ImageView)view.findViewById(R.id.item_picture); 
      this.itemCardView = (CardView)view.findViewById(R.id.card_view_list_item); 
      this.topParts = (LinearLayout)view.findViewById(R.id.card_view_list_item_top_part); 
      this.button1 = (ImageView)view.findViewById(R.id.item_button_1); 
      this.button2 = (ImageView)view.findViewById(R.id.item_button_2); 
     } 
    } 
} 

如果有人对我来说

的解决方案谢谢

回答

0

我找到了一个解决方案,我用的是onTouchListener在孩子recyclerView设置的scrollPosition(因为这种方法已被弃用我不使用onScrollListener)我实现一个getter这个领域摆脱滚动位置父RecyclerView等在父RecyclerView的onBindViewHolder的末尾调用(子)RecyclerView.scrollToPosition(scrollPosition)。

这就是使工作

家长RecyclerViewAdapter:

public class ProfilesCardViewListAdapter extends RecyclerView.Adapter<ProfilesCardViewListAdapter.ItemRowHolder> { 
    private ArrayList<AidodysProfile> sectionsList; 
    private Context context; 
    private boolean[] isShown; 
    private ProfileCardViewItemAdapter itemAdapters[]; 

    public ProfilesCardViewListAdapter(ArrayList<AidodysProfile> sectionsList, Context context) { 

     this.sectionsList = sectionsList; 
     this.context = context; 
     this.isShown = new boolean[sectionsList.size()]; 
     this.itemAdapters = new ProfileCardViewItemAdapter[sectionsList.size()]; 
     for (int i = 0; i < sectionsList.size(); i++) { 
      this.isShown[i] = true; 
      this.itemAdapters[i] = new ProfileCardViewItemAdapter(sectionsList.get(i).getProfiles(), context, this); 
     } 
    } 

    @Override 
    public ItemRowHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_card_view_horizontal, null); 
     final ItemRowHolder rowHolder = new ItemRowHolder(view); 
     rowHolder.itemRecyclerView.setLayoutManager(new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)); 
     return rowHolder; 
    } 

    @Override 
    public void onBindViewHolder(final ItemRowHolder holder, final int position) { 
     String sectionName = sectionsList.get(position).getName(); 

     AidodysProfile[] sectionItems = sectionsList.get(position).getProfiles(); 


     holder.sectionTitle.setTextSize(context.getResources().getDimension(R.dimen.text_size_profileslist_section_title)); 
     holder.sectionButton.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       showHideSection(holder, position); 
      } 
     }); 

     if (isShown[position]) { 
      holder.itemRecyclerView.setVisibility(View.VISIBLE); 
      holder.sectionButton.setText(context.getString(R.string.action_profiles_section_hide)); 
     } else { 
      holder.itemRecyclerView.setVisibility(View.GONE); 
      holder.sectionButton.setText(context.getText(R.string.action_profiles_section_show)); 
     } 

     if (!sectionsList.get(position).isLeaf()) { // FOLDER 
      if (sectionName.equals("")) { 
       holder.sectionTitle.setVisibility(View.GONE); 
       holder.sectionButton.setVisibility(View.GONE); 
      } else { 
       holder.sectionTitle.setVisibility(View.VISIBLE); 
       holder.sectionButton.setVisibility(View.VISIBLE); 
      } 
      holder.sectionTitle.setText(sectionName); 
     } else { // PROFILE 
      return; 
     } 

     holder.itemRecyclerView.setHasFixedSize(true); 
     holder.itemRecyclerView.setAdapter(itemAdapters[position]); 
     holder.itemRecyclerView.scrollToPosition(itemAdapters[position].getScrollPos()); 
    } 

    private void showHideSection(ItemRowHolder holder, int position) { 
     if (holder.itemRecyclerView.getVisibility() == View.VISIBLE) { 
      isShown[position] = false; 
      holder.itemRecyclerView.setVisibility(View.GONE); 
      holder.sectionButton.setText(context.getText(R.string.action_profiles_section_show)); 
     } else { 
      isShown[position] = true; 
      holder.itemRecyclerView.setVisibility(View.VISIBLE); 
      holder.sectionButton.setText(context.getString(R.string.action_profiles_section_hide)); 
     } 
    } 

    @Override 
    public int getItemCount() { 
     return (sectionsList != null ? sectionsList.size() : 0); 
    } 

    public class ItemRowHolder extends RecyclerView.ViewHolder { 

     protected TextView sectionTitle; 
     protected RecyclerView itemRecyclerView; 
     protected Button sectionButton; 

     public ItemRowHolder(View view) { 
      super(view); 
      this.sectionTitle = (TextView) view.findViewById(R.id.section_title); 
      this.itemRecyclerView = (RecyclerView) view.findViewById(R.id.item_recycler_view); 
      this.sectionButton = (Button) view.findViewById(R.id.section_button); 
     } 

    } 
} 

儿童RecyclerViewAdapter:

class ProfileCardViewItemAdapter extends RecyclerView.Adapter<ProfileCardViewItemAdapter.SingleItemRowHolder> { 
    private AidodysProfile[] itemsList; 
    private CurrentUser currentUser; 
    private Context context; 
    private int scrollPos = 0; 
    private ProfilesCardViewListAdapter parent; 

    public int getScrollPos() { 
     return scrollPos; 
    } 

    public ProfileCardViewItemAdapter(AidodysProfile[] itemsList, Context context, ProfilesCardViewListAdapter parent) { 
     this.itemsList = itemsList; 
     this.context = context; 
     this.parent = parent; 
     this.currentUser = CurrentUser.getInstance(context); 
    } 

    @Override 
    public SingleItemRowHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_card_view_horizontal, null); 
     SingleItemRowHolder rowHolder = new SingleItemRowHolder(view); 
     return (rowHolder); 
    } 

    @Override 
    public void onBindViewHolder(final SingleItemRowHolder holder, final int position) { 
     AidodysProfile profile = itemsList[position]; 

     holder.itemCardView.setOnTouchListener(new View.OnTouchListener() { 
      @Override 
      public boolean onTouch(View view, MotionEvent motionEvent) { 
       scrollPos = position; 
       return false; 
      } 
     }); 
     holder.itemCardView.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       selectProfile(holder, position); 
      } 
     }); 

     if (profile.getId() == currentUser.getProfile().getId()) { 
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 
       holder.itemCardView.setCardBackgroundColor(context.getColor(R.color.aidodysRed)); 
      } else { 
       holder.itemCardView.setCardBackgroundColor(context.getResources().getColor(R.color.aidodysRed)); 
      } 
     } else { 
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 
       holder.itemCardView.setCardBackgroundColor(context.getColor(R.color.white)); 
      } else { 
       holder.itemCardView.setCardBackgroundColor(context.getResources().getColor(R.color.white)); 
      } 
     } 

     holder.itemTitle.setText(profile.getName()); 

     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 
      holder.itemPicture.setImageDrawable(context.getDrawable(R.drawable.ic_sheet_smile_black_48dp)); 
      holder.button1.setImageDrawable(context.getDrawable(R.drawable.ic_edit_black_24dp)); 
      holder.button2.setImageDrawable(context.getDrawable(R.drawable.ic_look_profile)); 
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 
       holder.itemTitle.setTextAppearance(R.style.Aidodys_Text_ProfilesList_Item); 
       holder.itemPicture.setColorFilter(context.getColor(R.color.white)); 
       holder.topParts.setBackgroundColor(context.getColor(R.color.aidodysRed)); 
      } else { 
       holder.itemTitle.setTextColor(context.getResources().getColor(R.color.white)); 
       holder.itemTitle.setTextSize(context.getResources().getDimension(R.dimen.text_size_profileslist_item)); 
       holder.itemPicture.setColorFilter(context.getResources().getColor(R.color.white)); 
       holder.topParts.setBackgroundColor(context.getResources().getColor(R.color.aidodysRed)); 
      } 
     } else { 
      holder.button1.setImageDrawable(context.getResources().getDrawable(R.drawable.ic_edit_black_24dp)); 
      holder.button2.setImageDrawable(context.getResources().getDrawable(R.drawable.ic_look_profile)); 
      holder.itemTitle.setTextColor(context.getResources().getColor(R.color.white)); 
      holder.itemTitle.setTextSize(context.getResources().getDimension(R.dimen.text_size_profileslist_item)); 
      holder.itemPicture.setImageDrawable(context.getResources().getDrawable(R.drawable.ic_sheet_smile_black_48dp)); 
      holder.itemPicture.setColorFilter(context.getResources().getColor(R.color.white)); 
      holder.topParts.setBackgroundColor(context.getResources().getColor(R.color.aidodysRed)); 
     } 
    } 

    private void selectProfile(SingleItemRowHolder holder, int position) { 
     SharedPreferences.Editor editor = context.getSharedPreferences("Aidodys", 0).edit(); 
     editor.putString("profile", new Gson().toJson(itemsList[position])); 
     editor.apply(); 
     currentUser.setProfile(itemsList[position]); 
     parent.notifyDataSetChanged(); 
    } 

    @Override 
    public int getItemCount() { 
     return (itemsList != null ? itemsList.length : 0); 
    } 

    public class SingleItemRowHolder extends RecyclerView.ViewHolder { 

     protected TextView itemTitle; 
     protected ImageView itemPicture; 
     protected CardView itemCardView; 
     protected ImageView button1; 
     protected ImageView button2; 
     protected LinearLayout topParts; 

     public SingleItemRowHolder(View view) { 
      super(view); 

      this.itemTitle = (TextView)view.findViewById(R.id.item_title); 
      this.itemPicture = (ImageView)view.findViewById(R.id.item_picture); 
      this.itemCardView = (CardView)view.findViewById(R.id.card_view_list_item); 
      this.topParts = (LinearLayout)view.findViewById(R.id.card_view_list_item_top_part); 
      this.button1 = (ImageView)view.findViewById(R.id.item_button_1); 
      this.button2 = (ImageView)view.findViewById(R.id.item_button_2); 
     } 
    } 
} 
0

将x滚动偏移量存入一个SparseArray用于定位并在绑定视图持有者时恢复。

public class ProfilesCardViewListAdapter extends RecyclerView.Adapter<ProfilesCardViewListAdapter.ItemRowHolder> { 

    private SparseIntArray sparseArray = new SparseIntArray(); 

    @Override 
    public void onBindViewHolder(final ItemRowHolder holder, final int position) { 

     // Use srollBy for animate scrolling 
     holder.itemRecyclerView.srollBy(sparseArray.get(position, 0), 0); 
     // Or scrollTo for restore previous x offset 
     //holder.itemRecyclerView.srollTo(sparseArray.get(position, 0), 0); 

     holder.itemRecyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() { 

      @Override 
      public void onScrolled(RecyclerView recyclerView, int dx, int dy) { 
       sparseArray.put(position, dx); 
      } 
     } 
    } 
} 
+0

我考,我只是看到你的代码稍有不慎,你用两个时间scrollBy (它将滚动到第二次) –

+0

这不起作用...谢谢你的时间 –

+0

对不起我的错误。我没有想到,该itemRecyclerView尚未完成布局 – bvarga