在运行时动态地在recyclerView上添加部分(Java)

时间:2016-03-08 09:00:57

标签: java android android-recyclerview

我有一个带有一些值的RecyclerView现在我想为favourites添加另外一个用于defaults另一个的部分我可以像这样手动执行:

我有ChannelsAdapter来保存值:

public class ChannelsAdapter extends RecyclerView.Adapter<ChannelsAdapter.ChannelsViewHolder> implements Filterable  {

private LayoutInflater inflater;
private Context context;

List<ChannelsInformation> data = Collections.emptyList();

private final List<ChannelsInformation> filteredChannelsList;

private final MultiSelector mMultiSelector = new MultiSelector();

  ArrayList <String> selectedChannelName , selectedChannelID;

private HashMap<String, Boolean> map;


private TabFragment5 tabFragment5;


public ChannelsAdapter(Context context,  List<ChannelsInformation> data){

    inflater =  LayoutInflater.from(context);


    this.context = context;


    this.data = data;


    filteredChannelsList = data;
}

public void remove(int position){
    data.remove(position);
    notifyItemRemoved(position);
}


@Override
public ChannelsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

    View rowView = inflater.inflate(R.layout.custom_channel_row, parent, false);

    ChannelsViewHolder holder = new ChannelsViewHolder(rowView);

    return holder;
}

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

  final  ChannelsInformation current = data.get(position);

    holder.CHANNELNAME.setText(current.channelName);


    selectedChannelName  =  new ArrayList<String>();
    selectedChannelID =  new ArrayList<String>();

    holder.mSolvedCheckBox.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
           if (!selectedChannelID.contains(current.id)) {
                holder.mSolvedCheckBox.setChecked(true);
               selectedChannelName.add(current.channelName);
               selectedChannelID.add(current.id);

           } else {
                holder.mSolvedCheckBox.setChecked(false);

               selectedChannelName.remove(current.channelName);
               selectedChannelID.remove(current.id);

            }

        }
    });

}

@Override
public int getItemCount() {
    return data.size();
}

@Override
public Filter getFilter() {
    return new UserFilter(this ,filteredChannelsList);
}



private static class UserFilter extends Filter {

    private final ChannelsAdapter adapter;

    private final List<ChannelsInformation> originalList;

    private final List<ChannelsInformation> filteredList;

    private UserFilter(ChannelsAdapter adapter, List<ChannelsInformation> originalList) {
        super();
        this.adapter = adapter;
        this.originalList = new ArrayList<>(originalList);
        this.filteredList = new ArrayList<>();
    }

    @Override
    protected FilterResults performFiltering(CharSequence constraint) {
        filteredList.clear();
        final FilterResults results = new FilterResults();

        if (constraint == null || constraint.length() == 0) {
            filteredList.addAll(originalList);



        } else {
            final String filterPattern = constraint.toString().toLowerCase().trim();


            for (final ChannelsInformation channel : originalList) {

                if ( (channel.channelName != null && channel.channelName.toLowerCase().contains(filterPattern))
                        )

                {
                    filteredList.add(channel);

                }

            }
        }
        results.values = filteredList;
        results.count = filteredList.size();
        return results;
    }


    @Override
    protected void publishResults(CharSequence constraint, FilterResults results) {
        adapter.filteredChannelsList.clear();
        if  ((ArrayList<ChannelsInformation>) results.values != null ) {

            adapter.filteredChannelsList.addAll((ArrayList<ChannelsInformation>) results.values);
        }
        adapter.notifyDataSetChanged();

    } }






class ChannelsViewHolder extends SwappingHolder implements View.OnClickListener {

    TextView CHANNELNAME;
    CheckBox mSolvedCheckBox;




    public ChannelsViewHolder(View itemView) {


        super(itemView , mMultiSelector);

        mMultiSelector.setSelectable(true);

        mSolvedCheckBox = (CheckBox) itemView.findViewById(R.id.selectedChannelCheckBox);

        itemView.setOnClickListener(this);

        CHANNELNAME = (TextView) itemView.findViewById(R.id.ChannelNameTxtView);



    }

    @Override
    public void onClick(View v) {


           Toast.makeText(context, ""+CHANNELNAME.getText() ,Toast.LENGTH_SHORT).show();

        tabFragment5 = new TabFragment5();

        tabFragment5.addFavoriteSectionToRecyclerView(); // here am calling this function which is throwing me error 

    }

}}

我有另一个适用于SimpleSectionedRecyclerViewAdapter部分的适配器:

public class SimpleSectionedRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

private final Context mContext;
private static final int SECTION_TYPE = 0;

private boolean mValid = true;
private int mSectionResourceId;
private int mTextResourceId;
private LayoutInflater mLayoutInflater;
private RecyclerView.Adapter mBaseAdapter;
private SparseArray<Section> mSections = new SparseArray<Section>();


public SimpleSectionedRecyclerViewAdapter(Context context, int sectionResourceId, int textResourceId,
                                          RecyclerView.Adapter baseAdapter) {

    mLayoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    mSectionResourceId = sectionResourceId;
    mTextResourceId = textResourceId;
    mBaseAdapter = baseAdapter;
    mContext = context;

    mBaseAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
        @Override
        public void onChanged() {
            mValid = mBaseAdapter.getItemCount()>0;
            notifyDataSetChanged();
        }

        @Override
        public void onItemRangeChanged(int positionStart, int itemCount) {
            mValid = mBaseAdapter.getItemCount()>0;
            notifyItemRangeChanged(positionStart, itemCount);
        }

        @Override
        public void onItemRangeInserted(int positionStart, int itemCount) {
            mValid = mBaseAdapter.getItemCount()>0;
            notifyItemRangeInserted(positionStart, itemCount);
        }

        @Override
        public void onItemRangeRemoved(int positionStart, int itemCount) {
            mValid = mBaseAdapter.getItemCount()>0;
            notifyItemRangeRemoved(positionStart, itemCount);
        }
    });
}


public static class SectionViewHolder extends RecyclerView.ViewHolder {

    public TextView title;

    public SectionViewHolder(View view,int mTextResourceid) {
        super(view);
        title = (TextView) view.findViewById(mTextResourceid);
    }
}

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int typeView) {
    if (typeView == SECTION_TYPE) {
        final View view = LayoutInflater.from(mContext).inflate(mSectionResourceId, parent, false);

        return new SectionViewHolder(view,mTextResourceId);
    }else{

        return mBaseAdapter.onCreateViewHolder(parent, typeView -1);
    }
}

@Override
public void onBindViewHolder(RecyclerView.ViewHolder sectionViewHolder, int position) {
    if (isSectionHeaderPosition(position)) {
        ((SectionViewHolder)sectionViewHolder).title.setText(mSections.get(position).title);

    }else{
        mBaseAdapter.onBindViewHolder(sectionViewHolder,sectionedPositionToPosition(position));


    }

}

@Override
public int getItemViewType(int position) {
    return isSectionHeaderPosition(position)
            ? SECTION_TYPE
            : mBaseAdapter.getItemViewType(sectionedPositionToPosition(position)) +1 ;
}


public static class Section {
    int firstPosition;
    int sectionedPosition;
    CharSequence title;

    public Section(int firstPosition, CharSequence title) {
        this.firstPosition = firstPosition;
        this.title = title;
    }

    public CharSequence getTitle() {
        return title;
    }
}


public void setSections(Section[] sections) {
    mSections.clear();

    Arrays.sort(sections, new Comparator<Section>() {
        @Override
        public int compare(Section o, Section o1) {
            return (o.firstPosition == o1.firstPosition)
                    ? 0
                    : ((o.firstPosition < o1.firstPosition) ? -1 : 1);
        }
    });

    int offset = 0; // offset positions for the headers we're adding
    for (Section section : sections) {
        section.sectionedPosition = section.firstPosition + offset;
        mSections.append(section.sectionedPosition, section);
        ++offset;
    }

    notifyDataSetChanged();
}

public int positionToSectionedPosition(int position) {
    int offset = 0;
    for (int i = 0; i < mSections.size(); i++) {
        if (mSections.valueAt(i).firstPosition > position) {
            break;
        }
        ++offset;
    }
    return position + offset;
}

public int sectionedPositionToPosition(int sectionedPosition) {
    if (isSectionHeaderPosition(sectionedPosition)) {
        return RecyclerView.NO_POSITION;
    }

    int offset = 0;
    for (int i = 0; i < mSections.size(); i++) {
        if (mSections.valueAt(i).sectionedPosition > sectionedPosition) {
            break;
        }
        --offset;
    }
    return sectionedPosition + offset;
}

public boolean isSectionHeaderPosition(int position) {
    return mSections.get(position) != null;
}


@Override
public long getItemId(int position) {
    return isSectionHeaderPosition(position)
            ? Integer.MAX_VALUE - mSections.indexOfKey(position)
            : mBaseAdapter.getItemId(sectionedPositionToPosition(position));
}

@Override
public int getItemCount() {
    return (mValid ? mBaseAdapter.getItemCount() + mSections.size() : 0);
}

}

这是我的片段,我在这里添加值TabFragment5,如下所示:

        channelsAdapter = new ChannelsAdapter(getActivity(), getData()); // getting values

    recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));

    List<SimpleSectionedRecyclerViewAdapter.Section> sections =
            new ArrayList<SimpleSectionedRecyclerViewAdapter.Section>();

    //Sections , first section by default 

    sections.add(new SimpleSectionedRecyclerViewAdapter.Section(0, "All Channels")); 

    //Add your adapter to the sectionAdapter
    SimpleSectionedRecyclerViewAdapter.Section[] dummy = new SimpleSectionedRecyclerViewAdapter.Section[sections.size()];
    SimpleSectionedRecyclerViewAdapter mSectionedAdapter = new
            SimpleSectionedRecyclerViewAdapter(getActivity(),R.layout.section,R.id.section_text,channelsAdapter);
    mSectionedAdapter.setSections(sections.toArray(dummy));

    recyclerView.setAdapter(mSectionedAdapter);

//以上工作正常,但这是我想要完成的50%,我想在用户没有为收藏夹设置任何值时添加default部分,一旦用户制作任何值最喜欢的我想添加第二部分Favourites我不知道我怎么能在运行时动态地做到这一点,我试过这个当然不起作用我有一个错误:

    public  void addFavoriteSectionToRecyclerView(){


    Toast.makeText(context, "Function Called" ,Toast.LENGTH_SHORT).show();

    channelsAdapter = new ChannelsAdapter(getActivity(), getData());

    recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));


    List<SimpleSectionedRecyclerViewAdapter.Section> sections =
            new ArrayList<SimpleSectionedRecyclerViewAdapter.Section>();

    //Sections
    sections.add(new SimpleSectionedRecyclerViewAdapter.Section(0, "Favorites")); // adding second Section dynamically 
    sections.add(new SimpleSectionedRecyclerViewAdapter.Section(0, "All Channels"));

    //Add your adapter to the sectionAdapter
    SimpleSectionedRecyclerViewAdapter.Section[] dummy = new SimpleSectionedRecyclerViewAdapter.Section[sections.size()];
    SimpleSectionedRecyclerViewAdapter mSectionedAdapter = new
     SimpleSectionedRecyclerViewAdapter(getActivity(),R.layout.section,R.id.section_text,channelsAdapter);
    mSectionedAdapter.setSections(sections.toArray(dummy));

    recyclerView.setAdapter(mSectionedAdapter);

}

我的错误:

03-08 13:50:41.397 4237-4237/? E/AndroidRuntime: FATAL EXCEPTION: main
    Process: pb.myPackage, PID: 4237
    java.lang.NullPointerException
    at android.view.LayoutInflater.from(LayoutInflater.java:211)
    at pb.myPackage.ChannelsAdapter.<init>(ChannelsAdapter.java:52)
    at pb.myPackage.TabFragment5.addFavoriteSectionToRecyclerView(TabFragment5.java:420)
    at pb.myPackage.ChannelsAdapter$ChannelsViewHolder.onClick(ChannelsAdapter.java:236)
    at android.view.View.performClick(View.java:4469)
    at android.view.View$PerformClick.run(View.java:18468)
    at android.os.Handler.handleCallback(Handler.java:733)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:136)
    at android.app.ActivityThread.main(ActivityThread.java:5021)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:827)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:643)
    at dalvik.system.NativeStart.main(Native Method)

任何想法的人为什么会收到这个错误?如果是,那么请指出问题或者如果我在运行时添加此部分的方法不够好那么请建议我一个更好的方法,任何帮助或指导将非常感谢和帮助我,谢谢

P.S。为了添加这些部分,我遵循了这个SimpleSectionedRecyclerViewAdapter

更新:

请查看图片以便更好地理解,我有一个正常的RecyclerView,其中我推出名为section的{​​{1}}。现在默认情况下,只有第一个部分命名为default现在如果用户选择任何值作为收藏我想要添加另一个名为default的部分并将所选值移动到Favourites部分< / p>

i want to add values into another section like this

1 个答案:

答案 0 :(得分:2)

tabFragment5 = new TabFragment5();

tabFragment5.addFavoriteSectionToRecyclerView(); // here am calling this function which is throwing me error

如果TabFragment5确实是片段,那么上面的代码会构建一个全新的TabFragment5,然后调用addFavoriteSectionToRecyclerView()

在行之间阅读,我假设你想在TabFragment5的当前实例上调用此方法,并且你不想创建一个新方法。

为此,我建议的最简单的方法是使用EventBus

创建一个&#34;事件&#34;根据EventBus文件分类,即:

public class AddFavoriteSectionEvent {

    public AddFavoriteSectionEvent();

}

注册您的片段以收听事件:

    @Override
public void onStart() {
    super.onStart();
    EventBus.getDefault().register(this);
}

@Override
public void onStop() {
   EventBus.getDefault().unregister(this);
    super.onStop();
}

向Fragment添加方法以响应这些事件:

@Subscribe
public void onAddFavoriteEvent(AddFavoriteSectionEvent event){
    addFavoriteSectionToRecyclerView();
}

并替换导致您的NPE的两条线:

EventBus.getDefault().post(new AddFavoriteSectionEvent());

这应该至少解决你的NPE。