I saw few related questions about this kind of situation, but couldn't find any solution, so my problem goes like this.
I have tabLayout which hold's 4 fragments, Im delivering data to user in frag number 3 (catalog), this frag hold recyclerView for cardView im trying to implement onclicklistner for card which will invoke dialogFragment, I understand the most efficient way to do so, is using interface for the viewHolder, i face one problem the recyclerView adapter constructor .
Here is the the catalog frag:
public class CatalogFragment extends Fragment implements CustomAdapter.OnItemClickListener {
private FloatingActionButton mSharedFab;
private List<MyProducts> productsList;
//Creating Views
private RecyclerView recyclerView;
private RecyclerView.LayoutManager layoutManager;
private RecyclerView.Adapter adapter;
private CustomAdapter.OnItemClickListener listener;//////LISTNER FOR DIALOG???
//Volley Request
private RequestQueue requestQueue;
//request counter
private int requestCount = 1;
private static final String URL_INDEX = "http://myserverip/product.php";
//Tag values to read from json
public static final String TAG_IMAGE_URL = "product_img";
public static final String TAG_PRODUCT_SN = "product_serial_num";
public static final String TAG_PRODUCT_TITLE = "product_title";
public static final String TAG_PRODUCT_PRICE = "product_price";
public static final String TAG_PRODUCT_DESCRIPTION = "product_description";
public CatalogFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_catalog, container, false);
recyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
layoutManager = new LinearLayoutManager(getActivity().getApplicationContext(), LinearLayoutManager.VERTICAL, false);
recyclerView.setLayoutManager(layoutManager);
//recyclerView.setHasFixedSize(true);
RecyclerView.ItemAnimator itemAnimator = new DefaultItemAnimator();
itemAnimator.setAddDuration(1000);
itemAnimator.setRemoveDuration(1000);
recyclerView.setItemAnimator(itemAnimator);
//Initializing our product list
productsList = new ArrayList<>();
requestQueue = Volley.newRequestQueue(getActivity().getApplicationContext());
// fetch data
getData();
//initialize adapter
adapter = new CustomAdapter(listener, productsList, getActivity());
//Adding adapter to recyclerview
recyclerView.setAdapter(adapter);
return view ;
}
@Override
public void onItemClicked(View v) {
DialogAddToCartFragment df= new DialogAddToCartFragment();
df.show(getFragmentManager(), "Dialog");
}
the adapter instantiated with 3 params, with customadapter.
the customAdapter class:
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> {
public interface OnItemClickListener {
void onItemClicked(View v);
}
private OnItemClickListener listener;
//Image loader inst for image
private ImageLoader imageLoader;
private Context context;
public Snackbar snackbar;
String title;
//List all products
List<MyProducts> myProducts;
public CustomAdapter( OnItemClickListener listener, List<MyProducts> myProducts, Context context)
{
super();
this.listener = listener;
this.myProducts = myProducts;
this.context = context;
}
@Override
public CustomAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.product_list, parent, false);
ViewHolder viewHolder = new ViewHolder(v);
return viewHolder;
}
@Override
public void onBindViewHolder(CustomAdapter.ViewHolder holder, int position) {
if( myProducts != null) {
MyProducts myProducts1 = myProducts.get(position);
imageLoader = ImageVolley.getInstance(context).getImageLoader();
imageLoader.get(myProducts1.getProductImage(), ImageLoader.getImageListener(holder.imageView, R.drawable.android_store_log, android.R.drawable.ic_dialog_alert));
title = myProducts1.getProductTitle();
//Showing data to the views
holder.imageView.setImageUrl(myProducts1.getProductImage(), imageLoader);
holder.textViewProductTitle.setText(myProducts1.getProductTitle());
holder.textViewProductDescription.setText(myProducts1.getProductDescription());
holder.textViewProductSerialNumber.setText(myProducts1.getProductSn());
holder.textViewProductPrice.setText(myProducts1.getProductPrice());
}
}
@Override
public int getItemCount() {
return myProducts.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
//Views
public NetworkImageView imageView;
public TextView textViewProductTitle;
public TextView textViewProductDescription;
public TextView textViewProductSerialNumber;
public TextView textViewProductPrice;
//Initializing Views
public ViewHolder(final View itemView) {
super(itemView);
imageView = (NetworkImageView) itemView.findViewById(R.id.imageViewProduct);
textViewProductTitle = (TextView) itemView.findViewById(R.id.textViewProductTitle);
textViewProductDescription = (TextView) itemView.findViewById(R.id.textViewProductDescription);
textViewProductSerialNumber = (TextView) itemView.findViewById(R.id.textViewProductSerialNumber);
textViewProductPrice = (TextView) itemView.findViewById(R.id.textViewProductPrice);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
listener.onItemClicked(v);/////////DIALOG LISTENER????
}
});
}
}
the DialogFragment:
public class DialogAddToCartFragment extends DialogFragment {
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
View view = getActivity().getLayoutInflater().inflate(R.layout.fragment_dialog_add_to_cart, new LinearLayout(getActivity()), false);
// Retrieve layout elements
//TextView title = (TextView) view.findViewById(R.id.text_title);
// Set values
//title.setText("Not perfect yet");
// Build dialog
Dialog builder = new Dialog(getActivity());
builder.requestWindowFeature(Window.FEATURE_NO_TITLE);
builder.getWindow().setBackgroundDrawable(new ColorDrawable(Color.GREEN));
builder.setContentView(view);
return builder;
}
}
As i click on card i get program closed :(
Here is the log:
07-12 08:42:22.685 2808-2808/com.example.get2i.androidstore E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.get2i.androidstore, PID: 2808
java.lang.NullPointerException: Attempt to invoke interface method 'void com.example.get2i.androidstore.CustomAdapter$OnItemClickListener.onItemClicked(android.view.View)' on a null object reference
at com.example.get2i.androidstore.CustomAdapter$ViewHolder$1.onClick(CustomAdapter.java:102)
at android.view.View.performClick(View.java:5198)
at android.view.View$PerformClick.run(View.java:21147)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
With what should i instntiate the CustomAdapter.OnItemClickListener listener in the catalogfrag? Any advice would be appriciated, thank you!
instantiate the fragmentManager in the activity itself,
`FragmentManager fragmentManager = getFragmentManager();
adapter = new CustomAdapter(productsList, fragmentManager);`
`CustomAdapter implements MyClickListner{
CustomAdapter(Arraylist<MyProduct>productsList, FragmentManager
fragmentManager) {
this.productList = productsList;
this.fragmentManager = fragmentManager;
}
`@override
clickFunction(){
Fragment myFragment= new MyFilterFragment();
((MyFilterFragment) myFragment).show(this.fragmentManager,"tag");
}`
`public interface MyClickListener(){
public clickFunction();
}`
what should i instntiate the CustomAdapter.OnItemClickListener listener in the catalogfrag?
Because forget to initialize listener
object before passing it to CustomAdapter
class constructor. do it as:
listener=this;
adapter = new CustomAdapter(listener, productsList, getActivity());
...
call this method in onBindViewHolder
on itemView
's click listener
public void showDialogFragment(View view){
DialogFragment dialogFragment = DialogFragment.newInstance("Delete item","Are you sure you want to delete this item ?",R.drawable.cancel);
AppCompatActivity activity = ((AppCompatActivity)view.getContext());
dialogFragment.show(activity.getSupportFragmentManager(),null);
}
Hope it helps
Just change this in your CatalogFragment
adapter = new CustomAdapter(listener, productsList, getActivity());
To
adapter = new CustomAdapter(this, productsList, getActivity());
You're getting NPE because you are passing null reference of your listener
You're passing in an empty listener, not the one which you have implemented in your Fragment
instance.
Change this line;
adapter = new CustomAdapter(listener, productsList, getActivity());
to this;
adapter = new CustomAdapter(this, productsList, getActivity());
and delete your listener variable.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.