Can someone tell me what's wrong with this adapter? I'm getting an empty RecyclerView but a list that has 11 items in it? we have checked the customer class and the MainActivity and it seems to be correct. we log the customers.size in the getitems and find that there should be no trouble. could it be something wrong with the viewHolder class?
package com.example.jenso.test1yay;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.List;
import static android.content.ContentValues.TAG;
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private List<Customer> customers;
private Context context;
public MyAdapter(List<Customer> listItems ,Context context){
this.customers = listItems;
this.context = context;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_item,parent, false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
Customer customer = customers.get(position);
if (holder != null) {
holder.textViewHead.setText(customer.getName());
holder.textViewDesc.setText(customer.getLastName());
}
}
#Override
public int getItemCount() {
Log.d(TAG, "getItemCount: "+ customers.size());
return customers.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
public TextView textViewHead;
public TextView textViewDesc;
public ViewHolder(View itemView) {
super(itemView);
textViewHead = (TextView) itemView.findViewById(R.id.textViewHead);
textViewDesc = (TextView) itemView.findViewById(R.id.textViewDesc);
}
}
}
package com.example.jenso.test1yay;
import android.nfc.Tag;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private RecyclerView.Adapter adapter;
private List<Customer> customers;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
customers = new ArrayList<>();
for(int i = 1; i <= 10; i++){
Customer customer = new Customer("Jens" + (i+1),
"Svensson"
);
customers.add(customer);
}
adapter = new MyAdapter(customers, this);
recyclerView.setAdapter(adapter);
}
}
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.constraint.ConstraintLayout
android:id="#+id/cardView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="#+id/textViewDesc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="2dp"
android:text="Description"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/textViewHead" />
<TextView
android:id="#+id/textViewHead"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="2dp"
android:text="Heading"
android:textAppearance="#style/Base.TextAppearance.AppCompat.Large"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout>
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.jenso.test1yay.MainActivity">
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0"
tools:listitem="#layout/list_item" />
</android.support.constraint.ConstraintLayout>
Try change size of TextView android:layout_width="0dp" to 100dp
Late to the party, but try to pass the activity's Context into the adapter and then use that context in LayoutInflater.from instead of parent.getContext()
i make some correction in your code try it.
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private List<Customer> customers=new ArrayList<>();
private Context context;
public MyAdapter(List<Customer> listItems, Context context) {
this.customers = listItems;
this.context = context;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_item, parent, false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
Customer customer = customers.get(position);
if (holder != null) {
holder.textViewHead.setText(customer.getName());
holder.textViewDesc.setText(customer.getLastName());
}
}
#Override
public int getItemCount() {
Log.d(TAG, "getItemCount: " + customers.size());
return customers.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView textViewHead;
public TextView textViewDesc;
public ViewHolder(View itemView) {
super(itemView);
textViewHead = (TextView) itemView.findViewById(R.id.textViewHead);
textViewDesc = (TextView) itemView.findViewById(R.id.textViewDesc);
}
}
}
in main activity..
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private MyAdapter adapter;
private List<Customer> customers;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
customers = new ArrayList<>();
for(int i = 1; i <= 10; i++){
Customer customer = new Customer("Jens" + (i+1),
"Svensson"
);
customers.add(customer);
}
adapter = new MyAdapter(customers, this);
recyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
}
Related
i have a news app which i want when the news item (cardview) is clicked on, it should open another activity. unfortunately, nothing happens when the news item in the card view is clicked on, only when the background (recycler layout) is clicked on then the activity comes up.
i want when the news item on the cardview is clicked on, an activity should open and not when the background is clicked.
newsAdapter.java
package wami.ikechukwu.kanu;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import java.util.ArrayList;
public class newsAdapter extends RecyclerView.Adapter<newsAdapter.viewHolder> {
private ArrayList<dataModel> mDataModel;
private Context context;
private onclicklistener clicklistener;
public newsAdapter(Context context, ArrayList<dataModel> mDataModel, onclicklistener clicklistener) {
this.context = context;
this.mDataModel = mDataModel;
this.clicklistener = clicklistener;
}
#NonNull
#Override
public viewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view =
LayoutInflater.from(context).inflate(R.layout.recyclerview_layout,
viewGroup, false);
return new viewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull final newsAdapter.viewHolder viewHolder, final int i) {
dataModel dataModel = mDataModel.get(i);
viewHolder.mTextView.setText(dataModel.getTitle());
viewHolder.mTextDescrip.setText(dataModel.getDescrip());
Glide.with(context).load(dataModel.getImage()).into(viewHolder.mImageView);
}
#Override
public int getItemCount() {
return mDataModel.size();
}
public interface onclicklistener {
void onItemClick(int position);
}
public class viewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public TextView mTextView;
public ImageView mImageView;
public TextView mTextDescrip;
public viewHolder(#NonNull View itemView) {
super(itemView);
mTextView = itemView.findViewById(R.id.layout_text);
mImageView = itemView.findViewById(R.id.layout_image);
mTextDescrip = itemView.findViewById(R.id.layout_descrip);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
int adapterposition = getAdapterPosition();
clicklistener.onItemClick(adapterposition);
}
}
}
MainActivity.java
package wami.ikechukwu.kanu;
import android.app.AlertDialog;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.widget.Toast;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.Volley;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import dmax.dialog.SpotsDialog;
public class MainActivity extends AppCompatActivity implements newsAdapter.onclicklistener {
private final String KEY_AUTHOR = "author";
private final String KEY_TITLE = "title";
private final String KEY_DESCRIPTION = "description";
private final String KEY_URL = "url";
private final String KEY_URL_TO_IMAGE = "urlToImage";
private final String KEY_PUBLISHED_AT = "publishedAt";
//this string is appended to the url
String urlLink = "buhari";
ArrayList<dataModel> list;
private RecyclerView recyclerView;
private newsAdapter mAdapter;
private RecyclerView.LayoutManager mLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportActionBar().hide();
setContentView(R.layout.activity_main);
list = new ArrayList<>();
recyclerView = findViewById(R.id.recyclerView);
mAdapter = new newsAdapter(getApplicationContext(), list, this);
mLayout = new LinearLayoutManager(this);
recyclerView.setLayoutManager(mLayout);
recyclerView.setAdapter(mAdapter);
jsonParser();
}
private void jsonParser() {
final AlertDialog progressDialog = new SpotsDialog(this, R.style.customProgressDialog);
progressDialog.show();
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, "https://newsapi.org/v2/everything?q=" + urlLink + "&language=en&sortBy=publishedAt&pageSize=100&apiKey=655446a36e784e79b2b62adcad45be09", null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray jsonArray = response.getJSONArray("articles");
//Using a for loop to get the object (data) in the JSON
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
dataModel dataModel = new dataModel();
dataModel.setTitle(jsonObject.getString(KEY_TITLE));
dataModel.setImage(jsonObject.getString(KEY_URL_TO_IMAGE));
dataModel.setDescrip(jsonObject.getString(KEY_DESCRIPTION));
list.add(dataModel);
}
} catch (JSONException e) {
e.printStackTrace();
}
mAdapter.notifyDataSetChanged();
progressDialog.dismiss();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("Volley", error.toString());
progressDialog.dismiss();
}
});
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(jsonObjectRequest);
}
#Override
public void onItemClick(int position) {
Toast.makeText(this, "it worked " + position, Toast.LENGTH_SHORT).show();
Intent intent = new Intent(this, news_detail.class);
startActivity(intent);
}
}
recyclerview_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<android.support.v7.widget.CardView
android:id="#+id/recyclerviewlayout"
android:layout_width="match_parent"
android:layout_height="250dp"
android:layout_marginLeft="5dp"
android:layout_marginTop="10dp"
android:layout_marginRight="5dp"
android:clickable="true"
android:focusable="true"
app:cardCornerRadius="5dp"
app:cardElevation="10dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="250dp"
android:orientation="vertical">
<TextView
android:id="#+id/layout_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#FFFF"
android:ellipsize="end"
android:maxLines="1"
android:padding="5dp"
android:textColor="#F000"
android:textSize="17sp"
android:textStyle="bold" />
<ImageView
android:id="#+id/layout_image"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:contentDescription="#string/Recyclerview_ImageContent"
android:scaleType="centerCrop" />
<TextView
android:id="#+id/layout_descrip"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#FFFF"
android:ellipsize="end"
android:maxLines="3"
android:padding="5dp"
android:textColor="#F000"
android:textSize="15sp" />
<View
android:layout_width="match_parent"
android:layout_height="2dp"
android:background="#color/colorPrimaryDark" />
</LinearLayout>
</android.support.v7.widget.CardView>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical">
</android.support.v7.widget.RecyclerView>
In order to set onclick listener in recycler view, you have to follow as below
inner class ViewHolderItem(itemView: View) : RecyclerView.ViewHolder(itemView) {
init {
itemView.setOnClickListener {
clicklistener.onItemClick(adapterposition)
}
}
}
OnclickListener will work in Init block
I think should add setOnClickListener method in an onBindViewHolder
And in that you should call another activity with passing your parameter.
Example :- (in onBindViewHolder)
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// call activity.
Intent intent = new Intent(activity, anotherActivityname.class);
// For passing values
intent.putExtra(key,value);
startActivity(intent);
}
});
You have to modify your viewHolder in newsAdapter like following.
public class viewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public TextView mTextView;
public ImageView mImageView;
public TextView mTextDescrip;
public CardView yourCardView;
public viewHolder(#NonNull View itemView) {
super(itemView);
mTextView = itemView.findViewById(R.id.layout_text);
mImageView = itemView.findViewById(R.id.layout_image);
mTextDescrip = itemView.findViewById(R.id.layout_descrip);
yourCardView= itemView.findViewById(R.id.recyclerviewlayout);
// here you set on click listerner to your cardview.
yourCardView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
int adapterposition = getAdapterPosition();
clicklistener.onItemClick(adapterposition);
}
}
Hope it helps you.
How to make a specific item respond to click in recyclerView?
So for this make your card view clickable false and make your new item(View inside cardview) clickable true:
<Cardview..
android:clickable="false">
...............
......
<View..
android:clickable="true"/>
</Cardview>
Adapter
public class MoviesAdapter extends
RecyclerView.Adapter<MoviesAdapter.MoviesViewHolder> {
private static final String baseMovieUrl = "http://image.tmdb.org/t/p/w500";
private ArrayList<Movie> movies;
private Context context;
public MoviesAdapter(ArrayList<Movie> movies, Context context) {
this.movies = movies;
this.context = context;
}
#NonNull
#Override
public MoviesViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
return new MoviesViewHolder(layoutInflater.inflate(R.layout.movie_square, parent, false));
}
#Override
public void onBindViewHolder(#NonNull MoviesViewHolder holder, int position) {
holder.setData(position);
}
#Override
public int getItemCount() {
return movies.size();
}
public class MoviesViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private ConstraintLayout movieConstraint;
private TextView movieName;
private TextView movieRate;
private ImageView moviePoster;
public MoviesViewHolder(View itemView) {
super(itemView);
movieConstraint = itemView.findViewById(R.id.movie_holder_constraints);
movieName = itemView.findViewById(R.id.movie_name_tv);
movieRate = itemView.findViewById(R.id.movie_rating_tv);
moviePoster = itemView.findViewById(R.id.movie_iv);
movieConstraint.setOnClickListener(this);
}
public void setData(int position) {
movieConstraint.setTag(position);
movieName.setText(movies.get(position).getMovieName());
movieRate.setText(movies.get(position).getMovieRating() + "");
if (!Objects.equals(movies.get(position).getMovieUrl(), "") && movies.get(position).getMovieUrl() != null) {
Glide.with(moviePoster).load
(baseMovieUrl + movies.get(position).getMovieUrl())
.into(moviePoster);
} else Log.i("No url!", "No url!");
}
#Override
public void onClick(View view) {
int pos = (int) view.getTag();
view.setEnabled(false);
changeActivity(pos);
view.setEnabled(true); // TODO Find a way to prevent 2 acctivites to open simultaniously
}
private void changeActivity(int pos) {
Movie movie = movies.get(pos);
Intent intent = new Intent(context, MovieInfo.class);
intent.putExtra("movie", movie);
ActivityOptionsCompat options = ActivityOptionsCompat.
makeSceneTransitionAnimation((Activity) context, moviePoster, "profile");
context.startActivity(intent, options.toBundle());
}
}
}
and the xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/movie_holder_constraints"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="3dp">
<android.support.v7.widget.CardView
android:id="#+id/movie_cv"
android:layout_width="185dp"
android:layout_height="250dp"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:focusable="false"
android:focusableInTouchMode="false"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<android.support.constraint.ConstraintLayout
android:id="#+id/inside_movie_constraints"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusable="false"
android:focusableInTouchMode="false"
>
<ImageView
android:id="#+id/movie_iv"
android:layout_width="185dp"
android:layout_height="180dp"
android:scaleType="fitXY"
android:focusable="false"
android:focusableInTouchMode="false"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#mipmap/ic_launcher" />
<TextView
android:id="#+id/movie_rating_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="16dp"
android:layout_marginTop="2dp"
android:text="9.5"
android:textColor="#color/colorAccent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/movie_name_tv"
app:layout_constraintVertical_bias="1.0" />
<TextView
android:id="#+id/movie_name_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="Guardian's Of The Galaxy"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintHorizontal_weight="1"
android:gravity="center"
android:includeFontPadding="false"
app:layout_constraintTop_toBottomOf="#+id/movie_iv" />
</android.support.constraint.ConstraintLayout>
</android.support.v7.widget.CardView>
When clicking on the item in the recyclerView it wont open the activity or call the OnClickListener, after clicking another time the function is being called.
scrolling would also allow me to click on the items aswell.
I have heared changing the foucsable to false might solve this problem but as you can see in the xml it didn't.
Edit for adapter:
I changed the onClick to the onBindViewHolder, It fixed the problem although it doesn't feel to me like the right way to do it.
what do you say?
package com.example.galzaid.movies;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.constraint.ConstraintLayout;
import android.support.v4.app.ActivityOptionsCompat;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import java.util.ArrayList;
import java.util.Objects;
public class MoviesAdapter extends
RecyclerView.Adapter<MoviesAdapter.MoviesViewHolder> implements
View.OnClickListener {
private static final String baseMovieUrl = "http://image.tmdb.org/t/p/w500";
private ArrayList<Movie> movies;
private Context context;
public MoviesAdapter(ArrayList<Movie> movies, Context context) {
this.movies = movies;
this.context = context;
}
#NonNull
#Override
public MoviesViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
return new MoviesViewHolder(layoutInflater.inflate(R.layout.movie_square, parent, false));
}
#Override
public void onBindViewHolder(#NonNull MoviesViewHolder holder, int position) {
holder.setData(position);
holder.itemView.setOnClickListener(this);
holder.getAdapterPosition();
}
#Override
public int getItemCount() {
return movies.size();
}
#Override
public void onClick(View view) {
ImageView moviePoster = view.findViewById(R.id.movie_iv);
changeActivity((int) view.getTag(), moviePoster);
}
private void changeActivity(int pos, ImageView moviePoster) {
Movie movie = movies.get(pos);
Intent intent = new Intent(context, MovieInfo.class);
intent.putExtra("movie", movie);
ActivityOptionsCompat options = ActivityOptionsCompat.
makeSceneTransitionAnimation((Activity) context, moviePoster, "profile");
context.startActivity(intent, options.toBundle());
}
public class MoviesViewHolder extends RecyclerView.ViewHolder {
private ConstraintLayout movieConstraint;
private TextView movieName;
private TextView movieRate;
private ImageView moviePoster;
public MoviesViewHolder(View itemView) {
super(itemView);
movieConstraint = itemView.findViewById(R.id.movie_holder_constraints);
movieName = itemView.findViewById(R.id.movie_name_tv);
movieRate = itemView.findViewById(R.id.movie_rating_tv);
moviePoster = itemView.findViewById(R.id.movie_iv);
}
public void setData(int position) {
movieConstraint.setTag(position);
movieName.setText(movies.get(position).getMovieName());
movieRate.setText(movies.get(position).getMovieRating() + "");
if (!Objects.equals(movies.get(position).getMovieUrl(), "") && movies.get(position).getMovieUrl() != null) {
Glide.with(moviePoster).load
(baseMovieUrl + movies.get(position).getMovieUrl())
.into(moviePoster);
} else Log.i("No url!", "No url!");
}
}
}
I believe your problem is in this line
movieConstraint.setOnClickListener(this);
You shouldn't set it to ConstraintLayout, change the above line to this
itemView.setOnClickListener(this);
And there is nothing wrong in setting your onClickListener in a ViewHolder constructor.
EDIT:
In order to get the position in onClick you can use getAdapterPosition() method.
Set the OnClickListener in binding method, which in your case is public void setData(int position)
RecyclerView as its name says is reusing the views it created, so for every item you should set all the info from the start, including onClick listeners
That should fix your problems, and you will be able to resign from using setTag to differentiate the views
Avoid setting onClick listeners in ViewHolder constructors.
I have basic RecyclerView item with TextView and CheckBox. But when I click CheckBox, it does not work. All the more amazing it works when I long pressed.
I made a research and found android:descendantFocusability="blocksDescendants" , android:clickable="false", android:focusable="false" , android:longClickable="false" but they didn't help me
Here is my RecyclerView Item layout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:descendantFocusability="blocksDescendants">
<TextView
android:id="#+id/item_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="TextView"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:layout_marginLeft="10dp"
android:layout_marginStart="10dp"
android:textColor="#000000"/>
<android.support.v7.widget.AppCompatCheckBox
android:id="#+id/item_checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10dp"
android:layout_marginEnd="10dp"
app:buttonTint="#color/colorAccent"
android:focusable="false"
android:focusableInTouchMode="false"/>
</LinearLayout>
Here is my Adapter class
public class FilterTypeAdapter extends RecyclerView.Adapter<FilterTypeAdapter.MyViewHolder> {
private ArrayList<String> mData;
private Context mContext;
public FilterTypeAdapter() {
}
public FilterTypeAdapter(Context mContext, ArrayList<String> mData) {
this.mContext = mContext;
this.mData = mData;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int i) {
View v = LayoutInflater.from(mContext).inflate(R.layout.recycler_view_single_row, parent, false);
MyViewHolder vh = new MyViewHolder(v);
return vh;
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.mText.setText(mData.get(position));
holder.mCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
Toast.makeText(mContext, "Status is: " + isChecked + "", Toast.LENGTH_SHORT).show();
}
});
}
#Override
public int getItemCount() {
return mData.size();
}
// View Holder
public class MyViewHolder extends RecyclerView.ViewHolder {
private TextView mText;
private CheckBox mCheckBox;
public MyViewHolder(View itemView) {
super(itemView);
mText = itemView.findViewById(R.id.item_text);
mCheckBox = itemView.findViewById(R.id.item_checkbox);
}
}
}
I found everything working correctly here.
package <your_package>;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.AppCompatCheckBox;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CompoundButton;
import android.widget.TextView;
import android.widget.Toast;
import <your_package>.R;
import java.util.ArrayList;
public class TestActivity extends AppCompatActivity {
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test_recyclerview);
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
ArrayList<String> data = new ArrayList<>();
for(int i =0; i < 1000; i++) {
data.add(String.valueOf(i));
}
recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext(), LinearLayoutManager.VERTICAL, false));
recyclerView.setAdapter(new FilterTypeAdapter(getApplicationContext(), data));
}
public class FilterTypeAdapter extends RecyclerView.Adapter<MyViewHolder> {
private ArrayList<String> mData;
private HashMap<String, Boolean> mChecked;
private Context mContext;
public FilterTypeAdapter() {
}
public FilterTypeAdapter(Context mContext, ArrayList<String> mData) {
this.mContext = mContext;
this.mData = mData;
this.mChecked = new HashMap<>();
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int i) {
View v = TestActivity.this.getLayoutInflater().inflate(R.layout.test_recyclerview_item, parent, false);
MyViewHolder vh = new MyViewHolder(v);
return vh;
}
#Override
public void onBindViewHolder(final MyViewHolder holder, int position) {
holder.mText.setText(mData.get(position));
holder.mCheckBox.setOnCheckedChangeListener(null);
if(mChecked.containsKey(mData.get(position))) {
holder.mCheckBox.setChecked(mChecked.get(mData.get(position)));
}
else {
holder.mCheckBox.setChecked(false);
}
holder.mCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mChecked.put(mData.get(holder.getAdapterPosition()), isChecked);
Toast.makeText(mContext, "Status is: " + isChecked + "", Toast.LENGTH_SHORT).show();
}
});
}
#Override
public int getItemCount() {
return mData.size();
}
}
// View Holder
public class MyViewHolder extends RecyclerView.ViewHolder {
private TextView mText;
private AppCompatCheckBox mCheckBox;
public MyViewHolder(View itemView) {
super(itemView);
mText = (TextView) itemView.findViewById(R.id.item_text);
mCheckBox = (AppCompatCheckBox) itemView.findViewById(R.id.item_checkbox);
}
}
}
R.layout.test_recyclerview
<android.support.v7.widget.RecyclerView android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="30dp"
android:layout_marginEnd="10dp"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
xmlns:android="http://schemas.android.com/apk/res/android" />
R.layout.testrecyclerview_item
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/item_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:layout_marginLeft="10dp"
android:layout_marginStart="10dp"
android:textColor="#000000"/>
<android.support.v7.widget.AppCompatCheckBox
android:id="#+id/item_checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10dp"
android:layout_marginEnd="10dp"
app:buttonTint="#color/colorAccent"
/>
</LinearLayout>
remove these lines from checkbox widget
android:focusable="false"
android:focusableInTouchMode="false"
i think this may help
I m trying to add the value from textview dynamically to listview.For that I have created another layout to take the values from user. but I'm not able to do that. I have tried many things. Kindly help.. Here is my code.
package com.example.chetan.assignment;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ListAdapter;
import android.widget.ListView;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private static int count = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// String[] name= {"Apple","Banana","Mango","PineApple"};
//String[] price = {"Rs.40","Rs.60","Rs.70","Rs.80"};
List<String> names = new ArrayList<String>();
//String[] names = {"names"};
List<String> prices = new ArrayList<String>();
//String[] prices = {"prices"};
String name = getIntent().getStringExtra("name");
String price = getIntent().getStringExtra("price");
if(count==0) {
names.add(0, "name");
prices.add(0, "price");
}
if (count>0) {
names.add(count, name);
prices.add(count,price);
}
count++;
ListAdapter MyAdapter = new MyAdapter(names, prices, this);
ListView theList = (ListView) findViewById(R.id.listView);
theList.setAdapter(MyAdapter);
}
public void buttonClick(View view) {
Intent i = new Intent(this, Addlayout.class);
startActivity(i);
}
}
package com.example.chetan.assignment;
package com.example.chetan.assignment;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.TextView;
class MyAdapter extends BaseAdapter {
String[] name;
String[] price;
Context context;
private static LayoutInflater myInflater = null;
public MyAdapter(String[] name, String[] price, Context context) {
this.name = name;
this.price = price;
this.context = context;
myInflater = ( LayoutInflater )context.
getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return name.length;
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
public class Holder
{
TextView nametext;
TextView pricetext;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Holder myholder = new Holder();
View myViews = myInflater.inflate(R.layout.myview,parent,false);
myholder.nametext= (TextView) myViews.findViewById(R.id.textView);
myholder.pricetext= (TextView) myViews.findViewById(R.id.textView2);
myholder.nametext.setText(name[position]);
myholder.pricetext.setText(price[position]);
return myViews;
}
}
package com.example.chetan.assignment;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.Editable;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
public class Addlayout extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_addlayout);
}
public void Onclickbutton(View view){
EditText nametext = (EditText)findViewById(R.id.editText);
EditText pricetext = (EditText)findViewById(R.id.editText2);
String namedata = nametext.getText().toString();
String pricedata = pricetext.getText().toString();
Intent intent = new Intent(this,MainActivity.class);
intent.putExtra("name",namedata);
intent.putExtra("price",pricedata);
startActivity(intent);
}
}
Here you can do something like this:
Instead of simple listview I have used RecyclerView as it has better performance.
//First create a Data class for name and price
public class Data implements Serializable {
private String name,price;
public Data(){}
public Data(String name,String price){
this.name = name;
this.price = price;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
//your Addlayout class
public class Addlayout extends AppCompatActivity {
List<Data> dataList = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_addlayout);
}
public void Onclickbutton(View view){
EditText nameText = (EditText)findViewById(R.id.editText);
EditText priceText = (EditText)findViewById(R.id.editText2);
String nameData = nameText.getText().toString();
String priceData = priceText.getText().toString();
Data data = new Data(nameData, priceData);
dataList.add(data);
Intent intent = new Intent(this,MainActivity.class);
intent.putExtra("List", (Serializable) dataList);
startActivity(intent);
}
}
//add layout xml
//change layout according to you
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_addlayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.example.mmc.testproject.Addlayout">
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="textPersonName"
android:ems="10"
android:hint="name"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"
android:layout_marginStart="13dp"
android:id="#+id/editText" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="textPersonName"
android:ems="10"
android:hint="price"
android:layout_below="#+id/editText"
android:layout_alignEnd="#+id/editText"
android:layout_marginTop="18dp"
android:id="#+id/editText2" />
<Button
android:text="Button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/editText2"
android:layout_alignStart="#+id/editText2"
android:layout_marginStart="43dp"
android:layout_marginTop="36dp"
android:onClick="Onclickbutton"
android:id="#+id/button" />
</RelativeLayout>
//Then your Listview Adapter
public class ListViewAdaptor extends RecyclerView.Adapter<ListViewAdaptor.MyViewHolder> {
private List<Data> mDataList;
public class MyViewHolder extends RecyclerView.ViewHolder{
public TextView name,price;
public MyViewHolder(View view){
super(view);
name = (TextView) view.findViewById(R.id.name);
price= (TextView) view.findViewById(R.id.price);
}
}
public ListViewAdaptor(List<Data> dataList){
this.mDataList = dataList;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_view_item, parent, false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
Data data = mDataList.get(position);
holder.name.setText(data.getName());
holder.price.setText(data.getPrice());
}
#Override
public int getItemCount() {
return mDataList.size();
}
}
//your Listview layout to show name and price
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/name"
android:text="name"
android:gravity="center"
android:textSize="26sp"
android:layout_weight="1"/>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/price"
android:text="price"
android:gravity="center"
android:textSize="26sp"
android:layout_weight="1"/>
</LinearLayout>
//And finally the main Activity
public class MainActivity extends AppCompatActivity {
private RecyclerView mRecyclerView;
private ListViewAdaptor mAdapter;
private List<Data> mDataList;
private static final String TAG = "MainActivity";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
Intent i = getIntent();
mDataList = (List<Data>) i.getSerializableExtra("List");
Log.e(TAG,"Datalist size : "+mDataList.size());
mAdapter = new ListViewAdaptor(mDataList);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
mRecyclerView.setAdapter(mAdapter);
}
}
//and main Activity.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.example.mmc.testproject.MainActivity">
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/recycler_view">
</android.support.v7.widget.RecyclerView>
</RelativeLayout>
Hope it helps!!!
Here is my main_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.smartrix.horizontal_listview.MainActivity">
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
Here is my row.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_margin="12dp"
android:layout_width="150dp"
android:layout_height="250dp">
<TextView
android:id="#+id/title"
android:textStyle="bold"
android:textSize="20dp"
android:textAlignment="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</android.support.v7.widget.CardView>
Here is my mainActivity.java
package com.smartrix.horizontal_listview;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
private RecyclerView mRecyclerView;
private RecyclerView.LayoutManager mLayoutManager;
private RecyclerView.Adapter mAdapter;
private ArrayList<String> mDataSet;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mDataSet = new ArrayList<>();
for (int i = 0; i < 20; i++) {
mDataSet.add("New Title #"+i);
}
mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
mRecyclerView.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(this,LinearLayoutManager.HORIZONTAL,false);
mRecyclerView.setLayoutManager(mLayoutManager);
mAdapter = new MainAdapter(mDataSet);
mRecyclerView.setAdapter(mAdapter);
}
}
Here is my mainAdapter.java ::
package com.smartrix.horizontal_listview;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.ArrayList;
public class MainAdapter extends RecyclerView.Adapter<MainAdapter.ViewHolder> {
private ArrayList<String> mDataSet;
public MainAdapter(ArrayList<String> mDataSet){
this.mDataSet = mDataSet;
}
#Override
public MainAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.row, parent, false);
ViewHolder vh = new ViewHolder(v);
return vh;
}
#Override
public void onBindViewHolder(MainAdapter.ViewHolder holder, int position) {
holder.mTitle.setText(mDataSet.get(position));
}
#Override
public int getItemCount() {
return mDataSet.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView mTitle;
public ViewHolder(View itemView) {
super(itemView);
mTitle = (TextView) itemView.findViewById(R.id.title);
}
}
}
This Code Works Perfectly. Now I want to add this Horizontal ListView in Every ListItem of Vertical ListView. How to do this ??
You would simply add a new Horizontally oriented RecyclerView as an item in your list (and you would add it to your adapter).
It is fine to nest RelativeViews into each other.
In your case, add it to your row.xml layout, then inflate it in your mainAdapter.java class