问题
I have an activity with two sliding tabs(fragments). I want to create a header for Recyclerview dynamically, so that the user will get a dialogBox with an edittext in it. As soon as user clicks OK after typing the header name in the edittext, the string gets passed from activity to fragment. I have succeeded in transferring header name from activity to fragment using interface. A method in fragment will receive that string.
Method:
@Override
public void setDatainfo(String datainfo) {
Log.d("receivedset",datainfo);
AddSection(datainfo);
}
However, I need to use the received string to create a new header for the Recyclerview in that fragment tab, so it gets passed to AddSection() method. I have initialized the necessary classes already in onCreateView of that fragment. I simply need to do this in AddSection() method.
AddSection method:
public void AddSection(String datainfo){
MyadapterNew myadapterNew = new MyadapterNew(datainfo,getActivity(),R.layout.headerpond,R.layout.file_row_new,fDataset);
Log.d("received",datainfo);
sectionAdapter.addSection(myadapterNew);
sectionAdapter.notifyDataSetChanged();
}
It has to create a new header, but it is not creating one.
FragmentCode:
public class tab1 extends android.support.v4.app.Fragment implements home.infopass {
public ArrayList<String> fDataset = new ArrayList<>();
private Context context;
private SectionedRecyclerViewAdapter sectionAdapter;
RecyclerView fRecyclerView;
@Override
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View v =inflater.inflate(R.layout.tab1, container, false);
Log.d("tab1", "OncreateView");
registerForContextMenu(v);
sectionAdapter = new SectionedRecyclerViewAdapter();
MyadapterNew myadapterNew = new MyadapterNew("Pond1",getActivity(),R.layout.headerpond,R.layout.file_row_new,fDataset);
sectionAdapter.addSection(myadapterNew);
fRecyclerView = (RecyclerView) v.findViewById(R.id.file_tab);
fRecyclerView.setHasFixedSize(true);
RecyclerView.LayoutManager fLayoutManager = new LinearLayoutManager(this.getContext());
fRecyclerView.setLayoutManager(fLayoutManager);
fRecyclerView.setAdapter(sectionAdapter);
return v;
}
@Override
public void setDatainfo(String datainfo) {
Log.d("receivedset",datainfo);
AddSection(datainfo);
}
public void AddSection(String datainfo){
MyadapterNew myadapterNew = new MyadapterNew(datainfo,getActivity(),R.layout.headerpond,R.layout.file_row_new,fDataset);
Log.d("received",datainfo);
sectionAdapter.addSection(myadapterNew);
sectionAdapter.notifyDataSetChanged();
}
private class MyadapterNew extends StatelessSection {
List<String> data = new ArrayList<>(Arrays.asList("xyz", "abc", "xyhgz", "abygc"));
String header;
Context ctx;
Boolean Expanded = false;
public MyadapterNew(String header,Context ctx,int headerResourceId, int itemResourceId,ArrayList<String>data) {
super(headerResourceId, itemResourceId);
//this.data = data;
this.ctx=ctx;
this.header=header;
}
class HeaderViewHolder extends RecyclerView.ViewHolder {
TextView header;
public HeaderViewHolder(View view) {
super(view);
header = (TextView)view.findViewById(R.id.header);
}
}
class MyItemViewHolder extends RecyclerView.ViewHolder {
private TextView filename;
private ProgressBar file_progressbar;
private ImageView fileicon;
private ImageView upldownstatus;
private TextView filelength;
public MyItemViewHolder(View itemView) {
super(itemView);
filename = (TextView) itemView.findViewById(R.id.filename);
file_progressbar = (ProgressBar) itemView.findViewById(R.id.file_progressbar);
fileicon = (ImageView)itemView.findViewById(R.id.fileicon);
upldownstatus = (ImageView)itemView.findViewById(R.id.updownstatus);
filelength = (TextView)itemView.findViewById(R.id.filelength);
}
}
public void addItem(int position, String item) {
}
public void removeItem(int position) {
this.data.remove(position);
sectionAdapter.notifyDataSetChanged();
}
public void addHeader(int position, String item) {
}
public void removeHeader(int position) {
}
@Override
public RecyclerView.ViewHolder getItemViewHolder(View view) {
return new MyItemViewHolder(view);
}
@Override
public RecyclerView.ViewHolder getHeaderViewHolder(View view) {
return new HeaderViewHolder(view);
}
@Override
public void onBindItemViewHolder(RecyclerView.ViewHolder holder, final int position) {
final MyItemViewHolder itemHolder = (MyItemViewHolder) holder;
itemHolder.filename.setText(data.get(position));
final Animation animationFadeOut = AnimationUtils.loadAnimation(ctx, R.anim.fadeout);
itemHolder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("CLICKED", "TRUE");
itemHolder.itemView.setAnimation(animationFadeOut);
}
});
}
@Override
public void onBindHeaderViewHolder(RecyclerView.ViewHolder holder) {
super.onBindHeaderViewHolder(holder);
HeaderViewHolder headerViewHolder = (HeaderViewHolder) holder;
((HeaderViewHolder) holder).header.setText(header);
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Expanded=!Expanded;
sectionAdapter.notifyDataSetChanged();
}
});
}
@Override
public int getContentItemsTotal() {
return Expanded? data.size():0;
}
}
}
ERROR:
05-01 01:26:08.915 1571-1571/com.example.sandesh.filer E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.sandesh.filer, PID: 1571
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String io.github.luizgrp.sectionedrecyclerviewadapter.SectionedRecyclerViewAdapter.addSection(io.github.luizgrp.sectionedrecyclerviewadapter.Section)' on a null object reference
at com.example.sandesh.filer.tab1.AddSection(tab1.java:197)
at com.example.sandesh.filer.tab1.setDatainfo(tab1.java:90)
at com.example.sandesh.filer.home$3.onClick(home.java:313)
at android.support.v7.app.AlertController$ButtonHandler.handleMessage(AlertController.java:157)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5343)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:905)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:700)
回答1:
Your AddSection method seems correct, are you sure the onCreateView method is not being fired after the AddSection was called? please check in your logs.
回答2:
I solved My problem. As I suspected, Once the user entered header name, the header is passing into the fragment. However the string there is useless, as the sectionAdapter instance no longer exists to use that string and create a header. I have to get instance of fragment which is already instantiated in the beginning(when app starts). So here is what I did to get it work.
int position = tabLayout.getSelectedTabPosition
Fragment fragment = adapter.getFragment(tabLayout
.getSelectedTabPosition());
if (fragment != null) {
switch (position) {
case 0:
((tab1) fragment).AddSection(data);
break;
}
}
I have used above code to send header string to the fragment. As I am using pager for my TabLayout, I have implemented getfragment method to get the instance of already instantiated fragment in my pagerAdapter.
@Override
public Object instantiateItem(final ViewGroup container, final int position) {
final Fragment fragment = (Fragment) super.instantiateItem(container, position);
instantiatedFragments.put(position, new WeakReference<>(fragment));
return fragment;
}
@Override
public void destroyItem(final ViewGroup container, final int position, final Object object) {
instantiatedFragments.remove(position);
super.destroyItem(container, position, object);
}
@Nullable
public Fragment getFragment(final int position) {
final WeakReference<Fragment> wr = instantiatedFragments.get(position);
if (wr != null) {
return wr.get();
} else {
return null;
}
}
For more details, check this Link, Hope it is useful for someone
来源:https://stackoverflow.com/questions/36956323/sectionedrecyclerview-could-not-create-new-header-dynamically