i created Recycler view that shows the item list, however, only first top 10 are shown if i drag down the list repeat the randomly first 1~10 items, it should be shown like that
1
2
3
4
5
6
7
8
9
10
11
12
13
....
but
1
2
3
4
5
6
7
8
9
10 (till here good)
5
3
6
....(only repeating 1~10 number)
i attached the code, can someone get me the advice??
private RecyclerView mItemRecyclerView;
private LinearLayoutManager mLayoutManager;
private ItemAdapter mAdapter;
private TextView mTitleTextView;
private TextView mCostTextView;
private Button mBuyButton;
private Button mSellButton;
private Button mUse;
private Button mLeaveButton;
private GameData gmd;
#Override
public void onCreate(Bundle saveInstanceState)
{
super.onCreate(saveInstanceState);
setContentView(R.layout.recycler_view);
gmd = (GameData) getIntent().getSerializableExtra("gamedataToMarket");
mItemRecyclerView = findViewById(R.id.item_recycler_view);
mLayoutManager = new LinearLayoutManager(this);
mItemRecyclerView.setLayoutManager(mLayoutManager);
List<Item> items = gmd.getItems();
mAdapter = new ItemAdapter(items);
mItemRecyclerView.setAdapter(mAdapter);
mLeaveButton = findViewById(R.id.leave_Button);
mLeaveButton.setText(R.string.leave);
mLeaveButton.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
Intent rtn = new Intent();
rtn.putExtra("gameDataReturnFromMarKet",gmd);
setResult(1,rtn);
Toast.makeText(marketActivity.this, "back to navigation from market", Toast.LENGTH_SHORT).show();
finish();
}
});
FragmentManager fm2 = getSupportFragmentManager();
Fragment fragment2 = fm2.findFragmentById(R.id.status_recycler);
if(fragment2 == null){
fragment2 = new status_fragment();
fm2.beginTransaction()
.add(R.id.status_recycler,fragment2)
.commit();
}
}
private class ItemHolder extends RecyclerView.ViewHolder{
private Item mItems;
public ItemHolder(View view) {
super(view);
mTitleTextView = (TextView) itemView.findViewById(R.id.item_name);
mCostTextView = (TextView) itemView.findViewById(R.id.item_cost);
mBuyButton = (Button) itemView.findViewById(R.id.button_1_option);
mBuyButton.setText(R.string.bought);
mBuyButton.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
Toast.makeText(marketActivity.this, R.string.bought, Toast.LENGTH_SHORT).show();
}
});
mSellButton = (Button) itemView.findViewById(R.id.button_2_option);
mSellButton.setText(R.string.sold);
mSellButton.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
Toast.makeText(marketActivity.this, R.string.sold, Toast.LENGTH_SHORT).show(); // function for sell item
}
});
mUse = (Button) itemView.findViewById(R.id.button_3_option);
mUse.setText(R.string.use);
mUse.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
Toast.makeText(marketActivity.this, R.string.use, Toast.LENGTH_SHORT).show();
}
});
}
public void bind(Item item) {
mItems = item;
mTitleTextView.setText(item.getDescription());
mCostTextView.setText(String.valueOf(item.getValue()));
}
}
private class ItemAdapter extends RecyclerView.Adapter<ItemHolder> {
private List<Item> items;
public ItemAdapter(List<Item> item) {
items = item;
}
#Override
public ItemHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.holdingview,parent,false);
return new ItemHolder(v);
}
#Override
public void onBindViewHolder(ItemHolder holder, int position) {
holder.bind(items.get(position));
}
#Override
public int getItemCount() {
return items.size();
}
}
}
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="#+id/item_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="1dp"
android:layout_weight="0.8"
android:padding="1dp"
android:text="item name" />
<TextView
android:id="#+id/item_cost"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="1dp"
android:layout_weight="1"
android:padding="1dp"
android:text="cost" />
<Button
android:id="#+id/button_1_option"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1" />
<Button
android:id="#+id/button_2_option"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1" />
<Button
android:id="#+id/button_3_option"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1" />
</LinearLayout>
You have to make some changes in your code like this:
In ItemHolder class you are passing "view" in super method but getting by id using
"itemView".You have to find the id of view by using the same parameter that you
passing in super method.
so change all your findViewById like this:
mTitleTextView = (TextView) view.findViewById(R.id.item_name);
mCostTextView = (TextView) view.findViewById(R.id.item_cost);
You are declaring views (TextView and Button which you are using to populate data) in
activity and geting id in viewHolder.You have to declare them inside the viewholder.
In your case do it like this :
private class ItemHolder extends RecyclerView.ViewHolder {
private TextView mTitleTextView;
private TextView mCostTextView;
private Button mBuyButton;
private Button mSellButton;
private Button mUse;
public ItemHolder(View view) {
super(view);
mTitleTextView = (TextView) view.findViewById(R.id.item_name);
mCostTextView = (TextView) view.findViewById(R.id.item_cost);
mBuyButton = (Button) view.findViewById(R.id.button_1_option);
mSellButton = (Button) view.findViewById(R.id.button_2_option);
mUse = (Button) view.findViewById(R.id.button_3_option);
}
}
Related
I tried to implement an onClick method to my card recyclerView. When I click the card nothing happens but when I click the gap between the cards the intended action is performed. This was confirmed when as I tested this by increasing the spacing between the cards. What did I do wrong and how do I change my code to fix this problem?
This is the Adapter
public class JobListRecyclerAdapter extends RecyclerView.Adapter<JobListRecyclerAdapter.jobViewHolder> {
private ArrayList<JobClass> jobClassList;
private static OnItemClickListener clickListener;
public JobListRecyclerAdapter(ArrayList<JobClass> rList) {
this.jobClassList = rList;
}
#Override
public int getItemCount() {
if(jobClassList == null){return 0;}
return jobClassList.size();
}
#Override
public jobViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View itemView = LayoutInflater.
from(viewGroup.getContext()).
inflate(R.layout.job_list_card, viewGroup, false);
return new jobViewHolder(itemView);
}
#Override
public void onBindViewHolder(jobViewHolder jobViewHolder, int position) {
JobClass ci = jobClassList.get(position);
jobViewHolder.jName.setText("Name: "+ci.getmJobNum());
jobViewHolder.jDate.setText("Quantity: "+ci.getmJobDate());
}
public void setClickListener(OnItemClickListener itemClickListener) {
this.clickListener = itemClickListener;
}
public static class jobViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
protected TextView jName;
protected TextView jDate;;
public jobViewHolder(View j) {
super(j);
jName = (TextView) j.findViewById(R.id.job_name);
jDate = (TextView) j.findViewById(R.id.job_due_date);
itemView.findViewById(R.id.job_card_layout).setOnClickListener(this); // bind the listener
}
#Override
public void onClick(View view) {
if (clickListener != null) {clickListener.onClick(view, getLayoutPosition());}
}
}
}
This is the Activity
public class JobList extends Fragment implements OnItemClickListener {
public JobList() {
}
public static JobList newInstance() {
JobList fragment = new JobList();
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_job_list, container, false);
final RecyclerView recyclerView = (RecyclerView) rootView.findViewById(R.id.job_list_recycler_view);
LinearLayoutManager llm = new LinearLayoutManager(getContext());
recyclerView.setLayoutManager(llm);
final ArrayList<JobClass> joblistclass = new ArrayList<>();
/*
// Create a new Adapter
final ArrayAdapter<String> adapter = new ArrayAdapter<>(getActivity(),
android.R.layout.simple_list_item_1, android.R.id.text1);
*/
// Get a reference to the todoItems child items it the database
//String userPath = ((GlobalData) getActivity().getApplication()).getUserPath() +"JOBS";
//final DatabaseReference myRef = database.getReference(userPath);
// final DatabaseReference myRef = FirebaseDatabase.getInstance().getReference("USERS/04950F4AE53F80/JOBS");
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference jobsRef = rootRef
.child("USERS")
.child("04950F4AE53F80")
.child("JOBS");
// Assign a listener to detect changes to the child items
// of the database reference.
// myRef.addValueEventListener(new ValueEventListener() {
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot ds : dataSnapshot.getChildren()) {
String jobno = ds.child("JOBOVERVIEW").child("jobNum").getValue(String.class);
JobClass jblst = ds.child("JOBOVERVIEW").getValue(JobClass.class);
joblistclass.add(jblst);
((GlobalData) getContext().getApplicationContext()).saveJobNum(jobno);
}
final JobListRecyclerAdapter adapterb = new JobListRecyclerAdapter(joblistclass);
recyclerView.setAdapter(adapterb);
adapterb.setClickListener(JobList.this);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
};
jobsRef.addListenerForSingleValueEvent(eventListener);
///to send to next page
Button nextPage = (Button) rootView.findViewById(R.id.addNewJob);
// Capture button clicks
nextPage.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Start NewActivity.class
Intent myIntent = new Intent(getContext(), JobForm.class);
startActivity(myIntent);
}
});
return rootView;
}
#Override
public void onClick(View view, int position) {
ArrayList<String> nameArray = ((GlobalData) getActivity().getApplication()).getJobNums();
String name = nameArray.get(position);
((GlobalData) getActivity().getApplication()).setJobId(name);
Toast.makeText(getContext(), name,
Toast.LENGTH_LONG).show();
Intent intent = new Intent(getContext(), Main2Activity.class);
startActivity(intent);
}
}
Card View XML
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
app:cardUseCompatPadding="true"
android:id="#+id/job_card_layout"
android:layout_marginBottom="4dp"
android:clickable="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="100dp"
android:orientation="vertical"
android:id="#+id/job_linear_layout"
android:layout_marginRight="16dp"
android:layout_marginLeft="16dp"
android:layout_marginBottom="9dp"
android:clickable="true"
>
<TextView
android:id="#+id/job_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:clickable="true"
android:textSize="20sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/job_due_date"
android:layout_toRightOf="#+id/job_name"
android:clickable="true"
/>
</LinearLayout>
</android.support.v7.widget.CardView>
Please use below xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView android:id="#+id/job_card_layout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="4dp"
app:cardUseCompatPadding="true">
<LinearLayout
android:id="#+id/job_linear_layout"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_marginBottom="9dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:orientation="vertical">
<TextView
android:id="#+id/job_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:textSize="20sp" />
<TextView
android:id="#+id/job_due_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/job_name" />
</LinearLayout>
Note: android:clickable="true" has to be removed from your xml file.
Also, use
j.setOnClickListener(this);
instead of
itemView.setOnClickListener(this);
You don't have itemView field in your adapter or viewHolder as I can see. Maybe jobViewHolder should look like this:
jName = (TextView) j.findViewById(R.id.job_name);
jDate = (TextView) j.findViewById(R.id.job_due_date);
j.findViewById(R.id.job_card_layout).setOnClickListener(this); // bind the listener
Maybe your child view is placed at foreground and take all interactive from user. Let try this code in your child view xml.
android:duplicateParentState="true"
Update jobViewHolder class
Change following line
itemView.findViewById(R.id.job_card_layout).setOnClickListener(this); // bind the listener
to
j.findViewById(R.id.job_card_layout).setOnClickListener(this); // bind the listener
OR
j.setOnClickListener(this); // bind the listener
NOTE: If this doesn't work then you are referring wrong id i.e. job_card_layout
Updated JobViewHolder.java
public static class jobViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
protected TextView jName;
protected TextView jDate;;
public jobViewHolder(View j) {
super(j);
jName = (TextView) j.findViewById(R.id.job_name);
jDate = (TextView) j.findViewById(R.id.job_due_date);
itemView.setOnClickListener(this); // bind the listener
}
#Override
public void onClick(View view) {
if (clickListener != null) {clickListener.onClick(view, getLayoutPosition());}
}
}
I have a RecyclerView that shows images with checkboxes. When a checkbox is checked the items associated with the image get saved to a database. I also have an alphabet index that when clicked, calls a function that filters the images and updates the recycler view to show the images whose title correspond to alphabet letter clicked. The problem is that the RecyclerView images update only on the first click. There is no update to the RecyclerView images with subsequent clicks. I have checked and it appears that the function does get called with the subsequent clicks as I am able to display Toast messages throughout various points of the function. It is only the RecyclerView that is not updating with the filtered images data and I have no clue why it is not updating. Any help on this would be appreciated.
Here is the main activity:
public class AddBrandPage extends AppCompatActivity implements OnClickListener {
//declare variables
private RecyclerView recyclerView;
private RecyclerView.LayoutManager layoutManager;
private RecyclerView.Adapter adapter;
private RecyclerView alpharecyclerView;
private RecyclerView.LayoutManager alphaLayoutManager;
private RecyclerView.Adapter alphaAdapter;
private DatabaseReference myRef;
private DatabaseReference userRef;
private Button btn_skip;
private Button btn_save;
private CheckBox checkbox;
private String t;
private String letter;
List<LogoItems> brandLogo = new ArrayList<>();
//HashMap<String, String> saveBrands = new HashMap<>();
List<LogoItems> removedBrandLogo = new ArrayList<>();
List<String> selectionList = new ArrayList<>();
List<AlphaItems> alphaList = new LinkedList<>();
List<LogoItems> tmp = new ArrayList<>();
String[] alphabets = {"All", "A", "B", "C", "D", "E", "F", "G", "H", "I",
"J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"};
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_brand_page);
//initialize variables
btn_skip = (Button) findViewById(R.id.btn_skip);
btn_save = (Button) findViewById(R.id.btn_save);
myRef = FirebaseDatabase.getInstance().getReference().child("/brands");
userRef = FirebaseDatabase.getInstance().getReference().child("/users");
//calls to load data to arraylists
loadAlpha();
loadLogoImgData();
//set the listener for the buttons click event
btn_skip.setOnClickListener(this);
btn_save.setOnClickListener(this);
}
private void loadAlpha() {
for (String alpha : alphabets) {
alphaList.add(new AlphaItems(alpha));
}
startAlphaRecyclerView();
}
public void loadLogoImgData() {
brandLogo.clear();
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot brandSnapshot : dataSnapshot.getChildren()) {
LogoItems value = brandSnapshot.getValue(LogoItems.class);
brandLogo.add(value);
tmp.add(value);
}
startLogoRecyclerView();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
#Override
public void onClick(View view) {
if (view == btn_skip) {
//if skip button clicked close current window and go to user main page
finish();
startActivity(new Intent(getApplicationContext(), UserMainPage.class));
}
if (view == btn_save) {
saveData();
}
}
public void startLogoRecyclerView() {
// set the main recyclerview view for the logo in the layout
recyclerView = (RecyclerView) findViewById(R.id.recylView);
recyclerView.setHasFixedSize(true);
// set the main layoutManager of the logo recyclerview
layoutManager = new GridLayoutManager(this, 2);
recyclerView.setLayoutManager(layoutManager);
// set the logo recycler view adapter
adapter = new LogoAdapter(brandLogo, getBaseContext(), AddBrandPage.this);
recyclerView.setAdapter(adapter);
}
public void startAlphaRecyclerView() {
// set the main recyclerview view for the logo in the layout
alpharecyclerView = (RecyclerView) findViewById(R.id.alpharecyclerView);
alpharecyclerView.setHasFixedSize(true);
// set the main layoutManager of the alpha recyclerview
alphaLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
alpharecyclerView.setLayoutManager(alphaLayoutManager);
// set the alpha recycler view adapter
alphaAdapter = new AlphaAdapter(alphaList, getBaseContext(), AddBrandPage.this);
alpharecyclerView.setAdapter(alphaAdapter);
}
public List<String> prepareSelection(View v, int position) {
checkbox = (CheckBox) v;
//check if user selected checkbox and add or remove from list
//if (checkbox.isChecked()) {
selectionList.add(brandLogo.get(position).getName());
//} else {
// selectionList.remove(brandLogo.get(position).getLogo());
//}
return selectionList;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof AddBrandPage)) return false;
AddBrandPage that = (AddBrandPage) o;
if (t != null ? !t.equals(that.t) : that.t != null) return false;
return letter != null ? letter.equals(that.letter) : that.letter == null;
}
#Override
public int hashCode() {
int result = t != null ? t.hashCode() : 0;
result = 31 * result + (letter != null ? letter.hashCode() : 0);
return result;
}
public void updateLogoDisplay(final String letter) {
int i = 0;
brandLogo.clear();
brandLogo.addAll(tmp);
if (!(letter.equals("All"))) {
//Iterator<LogoItems> iter = brandLogo.iterator();
for (i=0; i< tmp.size(); i++){ //Iterator<LogoItems> iter = tmp.iterator(); iter.hasNext(); ) {
//while (iter.hasNext()) {
LogoItems r = tmp.get(i);
final String c = r.getName();
if (c != null) {
String t = c.substring(0, 1);
if (t != null) {
if (c != null) {
if ((letter.equals(t))) {
//brandLogo.remove(r);
removedBrandLogo.add(r);
//iter.remove();
}
}
}
} else {
}
}
brandLogo.clear();
brandLogo.addAll(removedBrandLogo);
adapter.notifyDataSetChanged();
//startLogoRecyclerView();
}
}
public void saveData() {
final FirebaseAuth mAuth;
final DatabaseReference userRef;
mAuth = FirebaseAuth.getInstance();
userRef = FirebaseDatabase.getInstance().getReference().child("users");
DatabaseReference curUser = userRef.child(mAuth.getCurrentUser().getUid());
curUser.child("brands").setValue(selectionList);//save selected items to the database
}
}
Here is the alphabet adapter(AlphaAdapter.java):
public class AlphaAdapter extends RecyclerView.Adapter<AlphaAdapter.AlphaViewHolder> {
//declare variables
List<AlphaItems> alphaList = new ArrayList<>();
private AddBrandPage addBrandPage;
private Context context;
//the constructor
public AlphaAdapter (List<AlphaItems> alphaList, Context context, AddBrandPage addBrandPage){
this.alphaList = alphaList;
this.context = context;
this.addBrandPage = addBrandPage;
}
#Override
public AlphaAdapter.AlphaViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.alpha_items, parent, false);
AlphaViewHolder alphaViewHolder = new AlphaViewHolder(view,addBrandPage);
return alphaViewHolder;
}
#Override
public void onBindViewHolder(AlphaAdapter.AlphaViewHolder holder, int position) {
holder.txt_alpha.setText(alphaList.get(position).getLetter());
}
#Override
public int getItemCount() {
return alphaList.size();
}
public class AlphaViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
//declare variables
private TextView txt_alpha;
private AddBrandPage addBrandPage;
//the constructor
public AlphaViewHolder (View itemView, AddBrandPage addBrandPage){
super(itemView);
this.addBrandPage = addBrandPage;
//initialize variables
txt_alpha = (TextView) itemView.findViewById(R.id.txt_alpha);
//set click listener
txt_alpha.setOnClickListener(this);
}
#Override
public void onClick(View v) {
int position = getAdapterPosition();
String letter = alphaList.get(position).getLetter();
addBrandPage.updateLogoDisplay(letter);
}
}
}
Here is the alphabet index layout(alpha_items.xml):
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="40dp"
android:layout_height="match_parent"
android:scrollbars="horizontal">
<android.support.v7.widget.CardView
android:layout_width="40dp"
android:layout_height="40dp"
android:scrollbars="horizontal"
>
<TextView
android:id="#+id/txt_alpha"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center_vertical"
android:layout_marginLeft="15dp"
android:layout_marginRight="2dp"
android:text="A"
android:textSize="18dp"
android:focusable="false"
android:focusableInTouchMode="false"
android:gravity="center_vertical"
/>
</android.support.v7.widget.CardView>
</LinearLayout>
Here is the logo adapter that displays the images (LogoAdapter.java):
public class LogoAdapter extends RecyclerView.Adapter<LogoAdapter.LogoViewHolder> {
public static LogoAdapter adapter;
//declaration fo variables
List<LogoItems> brandLogo = new ArrayList<>();
List<String> selector = new ArrayList<>();
private AddBrandPage addBrandPage;
private Context context;
private CheckBox checkbox;
//the constructor
public LogoAdapter(List<LogoItems> brandLogo, Context context, AddBrandPage addBrandPage) {
this.brandLogo = brandLogo;
this.context = context;
this.addBrandPage = addBrandPage;
}
#Override
public LogoAdapter.LogoViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.logo_items, parent, false);
LogoViewHolder logoViewHolder = new LogoViewHolder(view,addBrandPage);
return logoViewHolder;
}
#Override
public void onBindViewHolder(LogoAdapter.LogoViewHolder holder, int position) {
Picasso.with(context).load(brandLogo.get(position).getLogo()).into(holder.logo);
}
#Override
public int getItemCount() {
return brandLogo.size();
}
//viewholder class
public class LogoViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
//declare variables
private AddBrandPage addBrandPage;
private ImageView logo;
private CheckBox checkbox;
//ViewHolder constructor
public LogoViewHolder(View itemView, AddBrandPage addBrandPage) {
super(itemView);
//initialize variables inside the viewholder constructor
this.addBrandPage = addBrandPage;
logo = (ImageView) itemView.findViewById(R.id.img_logo);
checkbox = (CheckBox) itemView.findViewById(R.id.checkbox);
//set click listener for the checkbox
checkbox.setOnClickListener(this);
logo.setOnClickListener(this);
}
#Override
public void onClick(View v) {
int position = getAdapterPosition();
addBrandPage.prepareSelection(v, position);//method call to populate an arraylist with selected items
}
}
}
Here is the xml layout of the images (Logo_items.xml)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:cardView="http://schemas.android.com/apk/res-auto"
android:id="#+id/logo_container"
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="#android:color/darker_gray"
android:gravity="center_vertical|center_horizontal"
android:orientation="vertical"
android:paddingBottom="10dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="10dp"
android:visibility="visible"
cardView:layout_collapseParallaxMultiplier="1.0">
<android.support.v7.widget.CardView
android:layout_width="155dp"
android:layout_height="100dp"
android:layout_marginBottom="5dp"
android:layout_marginTop="5dp"
cardView:cardBackgroundColor="#android:color/white">
<GridLayout
android:id="#+id/cardView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal|center_vertical"
android:orientation="vertical">
<ImageView
android:id="#+id/img_logo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_column="1"
android:layout_gravity="center_horizontal|center_vertical"
android:layout_row="0"
android:paddingBottom="5dp"
android:paddingLeft="2.5dp"
android:paddingRight="2.5dp"
android:paddingTop="5dp">
</ImageView>
</GridLayout>
<CheckBox
android:id="#+id/checkbox"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginLeft="130dp"
android:layout_marginTop="66dp"
android:onClick="addBrandpage.prepareSelection"
/>
</android.support.v7.widget.CardView>
</LinearLayout>
Here is the logcat:
06-16 09:16:24.404 12319-12324/com.test.test I/art: Do partial code cache collection, code=499KB, data=310KB
06-16 09:16:24.429 12319-12324/com.test.test I/art: After code cache collection, code=499KB, data=315KB
06-16 09:16:24.429 12319-12324/com.test.test I/art: Increasing code cache capacity to 2MB
06-16 09:16:32.258 12319-12326/com.test.test W/art: Suspending all threads took: 13.640ms
06-16 09:16:32.260 12319-12319/com.test.test I/Choreographer: Skipped 53 frames! The application may be doing too much work on its main thread.
I was able to solve the problem.
There are two OnClickListeners on the activity page. One for the checkboxes and one for the alphabet index. What was happening is that when an alphabet letter gets clicked, both OnClickListeners get triggered. So on the first click, the alphabet OnClickListener executes to completion and the RecyclerView updates with the filtered images. But on the second click, while it appears to execute the function, the function does not fully complete as the program gets confused with the checkbox OnClickListener. The solution is to add an if(condition) to the onClick method so that the program knows which OnClickListener the click applies to. The modification made in the AlphaAdapter class was as follows:
#Override
public void onClick(View view) {
if (view == txt_alpha) {
int position = getAdapterPosition();
String letter = alphaList.get(position).getLetter();
addBrandPage.updateLogoDisplay(letter);
}
}
A similar modification was made to the LogoAdapter class.
i already success to make one Recyclerview and i want to add new Recyclerview Horizontal on top. i will explain in my code :
<android.support.v7.widget.RecyclerView
android:id="#+id/arrayListUser"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:divider="#color/white">
</android.support.v7.widget.RecyclerView>
<android.support.v7.widget.RecyclerView
android:id="#+id/arrayList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:divider="#color/white">
</android.support.v7.widget.RecyclerView>
id:arrayList is my first Recyclerview have name xml feeds_listview
id:arrayListUser is my new Recyclerview, i want make this Recyclerview Horizontal
xml for new Recylerview is feeds_listviewUser
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<de.hdodenhof.circleimageview.CircleImageView
android:id="#+id/profil"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginBottom="5dp"
android:layout_marginTop="30dp"
android:layout_gravity="center"
android:src="#drawable/cthprofil" />
<TextView
android:id="#+id/fullName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_marginTop="5dp"
android:layout_marginBottom="20"
android:text="Megi Fernanda"
android:textSize="17sp"
android:textColor="#color/colordefault"
android:textStyle="bold" />
</LinearLayout>
and this is my class adapter
public class FeedsCustomAdapter extends RecyclerView.Adapter<FeedsCustomAdapter.ViewHolder> {
private Context context;
private List<FeedsAdapter> feeds_list;
private ArrayList<Feeds> mFeedsList = new ArrayList<Feeds>();
private OnItemClickListener mListener;
private OnItemClickListener mListener2;
public FeedsCustomAdapter(Context context, ArrayList<Feeds> mFeedsList) {
this.context = context;
this.mFeedsList = mFeedsList;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.feeds_listview, parent, false);
return new ViewHolder(itemView);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
Feeds feed = getFeeds().get(position);
int textColor = context.getResources().getColor(R.color.btn_next);
int textColor2 = context.getResources().getColor(R.color.text_color_black);
holder.fullName.setText(feed.user.fullName);
holder.location.setText(feed.user.location);
holder.topic.setText(Html.fromHtml( "Menyelesaikan Tantangan " + " <font color = '" + String.valueOf(textColor2) + "'>" + feed.topic + "</font>" ) );
Picasso.with(context)
.load(feed.user.avatar)
.into(holder.profile);
PrettyTime prettyTime = new PrettyTime();
String times = prettyTime.format(DateUtil.timeMilisTodate(feed.timestamp * 1000));
holder.times.setText(times);
}
#Override
public int getItemCount() {
return mFeedsList.size();
}
public ArrayList<Feeds> getFeeds() {
return mFeedsList;
}
public void setComplete(int position) {
mFeedsList.get(position).isComplete = 1;
}
public boolean last() {
boolean result = false;
int total = mFeedsList.size();
for (int i = 0; i < mFeedsList.size(); i++) {
if (mFeedsList.get(i).isComplete == 1) {
total--;
}
}
if (total == 1) {
result = true;
}
return result;
}
class ViewHolder extends RecyclerView.ViewHolder {
public TextView fullName;
public TextView location;
public TextView topic;
public ImageView profile;
public TextView times;
public ViewHolder(View itemView) {
super(itemView);
fullName = (TextView) itemView.findViewById(R.id.fullName);
location = (TextView) itemView.findViewById(R.id.location);
topic = (TextView) itemView.findViewById(R.id.topic);
profile = (ImageView) itemView.findViewById(R.id.profil);
times = (TextView) itemView.findViewById(R.id.times);
profile.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(mListener2 != null){
mListener2.onItemClick2(v ,getPosition());
}
}
});
topic.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(mListener != null){
mListener.onItemClick(v ,getPosition());
}
}
});
}
}
public void setClickListener(OnItemClickListener clickListener) {
this.mListener = clickListener;
}
public void setClickListenerProfile(OnItemClickListener clickListener2){
this.mListener2 = clickListener2;
}
public interface OnItemClickListener {
public abstract void onItemClick(View view, int position);
public abstract void onItemClick2(View view, int position);
}
so, in my code i success to display first recylerview with my first xml and i want add new recylerview horizontal with new xml feeds_listviewUser
You can use LinearLayout to wrap both recyclerView.
<android.support.v7.widget.RecyclerView
android:id="#+id/arrayListUser"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="#color/white">
</android.support.v7.widget.RecyclerView>
<android.support.v7.widget.RecyclerView
android:id="#+id/arrayList"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:divider="#color/white">
</android.support.v7.widget.RecyclerView>
And assign horizontal layout manager to one recyclerview and vertical layout manager to other
LinearLayoutManager userManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
arrayListUser.setLayoutManager(userManager);
LinearLayoutManager listManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
arrayList.setLayoutManager(listManager);
Put your recyclerviews in Relative layout.
First add horizontal recyclerView to alignParentTop true and fix height according to visibility of feeds_listviewUser next add vertical recyclerView with layout_below horizontal recyclerview id.
I'm new to Android programming and trying to set a click listener to open another activity. The list loads fine, but when I click the items, nothing happens. This is my adapter:
public interface OnItemClickListener {
void onItemClick(Product product);
}
private List<Product> productList;
private double currentLatitude, currentLongitude;
private Context context;
private final OnItemClickListener listener;
public AdapterForProducts(List<Product> productList, OnItemClickListener listener, double currentLatitude, double longitude, Context context){
this.currentLatitude = currentLatitude;
this.currentLongitude = longitude;
this.productList = productList;
this.context = context;
this.listener = listener;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_layout, parent, false);
ViewHolderForProducts holder = new ViewHolderForProducts(view);
return holder;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
//Use the provided View Holder on the onCreateViewHolder method to populate the current row on the RecyclerView
ViewHolderForProducts holder = (ViewHolderForProducts) viewHolder;
Product product = productList.get(position);
String distanceText = "Distancia: " + round(distance(product.getLatitude(), product.getLongitude())) + " meters";
holder.bind(productList.get(position), listener, distanceText);
}
#Override
public int getItemCount() {
return productList.size();
}
the viewHolder:
public ViewHolderForProducts(View view){
super(view);
cardView = (CardView) itemView.findViewById(R.id.cardView);
name = (TextView) view.findViewById(R.id.product_name);
value = (TextView) view.findViewById(R.id.product_value);
distance = (TextView) view.findViewById(R.id.product_distance);
}
public void bind(final Product product, final AdapterForProducts.OnItemClickListener listener,
String distanceText) {
name.setText(product.getName());
value.setText("Preço: " + product.getValue());
distance.setText(distanceText);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
listener.onItemClick(product);
}
});
}
And I'm calling it in the activity like this:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search_and_show_product_list);
Bundle extras = getIntent().getExtras();
if (extras != null) {
latitude = extras.getDouble("latitude");
longitude = extras.getDouble("longitude");
}
query = "";
query_field = (EditText) findViewById(R.id.query_field);
searchButton = (Button) findViewById(R.id.searchProductButton);
requestQueue = Volley.newRequestQueue(getApplicationContext());
recyclerView = (RecyclerView) findViewById(R.id.recycler);
productList = new ArrayList<>();
fillProductListByName();
adapterForProducts = new AdapterForProducts(productList, new AdapterForProducts.OnItemClickListener() {
#Override
public void onItemClick(Product product) {
showProductOnMap(product);
}
}, latitude, longitude, getApplication());
recyclerView.setAdapter(adapterForProducts);
adapterForProducts.notifyDataSetChanged();
recyclerView.setLayoutManager(new LinearLayoutManager(this));
searchButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
query = query_field.getText().toString();
productList.clear();
fillProductListByName();
adapterForProducts.notifyDataSetChanged();
}
});
}
This is the list item xml:
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/cardView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="#dimen/activity_vertical_margin"
android:clickable="true"
android:focusable="true"
android:foreground="?android:attr/selectableItemBackground"
app:cardCornerRadius="#dimen/activity_vertical_margin"
app:cardElevation="#dimen/activity_vertical_margin">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/colorAccent"
android:clickable="true"
android:padding="16dp">
<ImageView
android:id="#+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginRight="16dp" />
<TextView
android:id="#+id/product_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/imageView"
android:layout_toRightOf="#+id/imageView"
android:text="Product Name"
android:textSize="14sp" />
<TextView
android:id="#+id/product_value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginLeft="15dp"
android:layout_marginStart="15dp"
android:layout_toRightOf="#+id/product_name"
android:text="Price: " />
<TextView
android:id="#+id/product_distance"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="51dp"
android:layout_marginStart="51dp"
android:layout_toEndOf="#+id/product_value"
android:layout_toRightOf="#+id/product_value"
android:text="Distance:" />
</RelativeLayout>
I got it working. Apparently, this implementation doesn't work if there is some other clickable object inside the list item, as was the case with:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/colorAccent"
android:clickable="true"
android:padding="16dp">
All I did was to erase the android:clickable="true" from the RelativeLayout
When you set the attr android:clickable="true" to the parent layout, its click method
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
listener.onItemClick(product);
}
});
will only be called if its childs doesn't have the clickable = true or have a OnClickListener set.
Actually, you don't need all these android:clickable="true".
When you set android:clickable="true" you are setting a empty ClickListener to this view.
The click event is passed to the lowest view in the layout hierarchy with a ClickListener implemented, even with empty body. This is the cause of your bug, and its because of this that you have to remove the android:clickable="true".
Removing the android:clickable="true", removes the empty ClickListener, and now the lowest view in the layout hierarchy is the CardView with this ClickListener:
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
listener.onItemClick(product);
}
});
So, this is the ClickListener that will be called.
I've got a RecyclerView which populates from an ArrayList. The output is a CardView layout.
In the Cardview, there are 2 buttons amongst other Views.
They only have to read the current value of a TextView, which by default is 1, and increase or decrease it.
The Arraylist contains 8 items.
When I run the app the UI works fine. Trouble is when I try to modify the value of the TextView.
The value is correctly increased and decreased on the CardView I'm working on, but ALSO the value is modified on another CardView. And in that second CardView, modifying its TextView value, also modifies the first one.
So, what am I doing wrong?
This is my Fragment:
public class Fragment_rosas extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.layout_rosas,container,false);
RecyclerView recyclerview_rosas;
RecyclerView.Adapter adaptador_rv_rosas;
RecyclerView.LayoutManager lm_rosas;
List rosas = new ArrayList();
rosas.add(new Tropa(1,R.drawable.minibarbaro, getResources().getString(R.string.barbaro),7,1));
recyclerview_rosas = (RecyclerView) view.findViewById(R.id.recyclerView_tropasRosas);
recyclerview_rosas.setHasFixedSize(true);
lm_rosas = new LinearLayoutManager(getContext());
recyclerview_rosas.setLayoutManager(lm_rosas);
adaptador_rv_rosas = new AdaptadorTropa(rosas);
recyclerview_rosas.setAdapter(adaptador_rv_rosas);
return view;
}
}
And here the part of code on my Adapter:
#Override
public void onBindViewHolder(final TropaViewHolder viewHolder, int i) {
viewHolder.imagen.setImageResource(items.get(i).getImagen());
viewHolder.nombre.setText(items.get(i).getNombre());
viewHolder.maxnivel.setText(String.valueOf(items.get(i).getNivelMax()));
viewHolder.espacioencamp.setText((String.valueOf(items.get(i).getEspacioEnCamp())));
final String nombre = items.get(i).getNombre();
final int maxnivel = items.get(i).getNivelMax();
viewHolder.nivelmas.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String niveltemp = viewHolder.nivel.getText().toString();
String nivelmaxtemp = viewHolder.maxnivel.getText().toString();
int nivel = Integer.parseInt(niveltemp);
int maxxnivel = Integer.parseInt(nivelmaxtemp);
int nuevonivel = nivel+1 ;
if (nuevonivel<=maxxnivel) {
viewHolder.txtv_nivel.setText(String.valueOf(nuevonivel));
}
}
});
My OnCreateViewHolder (nothing really happens here):
#Override
public TropaViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.cardview, viewGroup, false);
return new TropaViewHolder(v);
}
Here is the solution, as mentioned in the comment above, it addresses two problems:
1. positiontoValueMap - saves current value for each position
2. onclicklistener is passed to the ViewHolder in onCreateViewHolder
Adapter Class
public class MyAdapter extends RecyclerView.Adapter {
private Context context;
private List<String> dataList;
private Map<Integer, Integer> positionToValueMap = new HashMap<>();
public MyAdapter(Context context, List<String> dataList) {
this.context = context;
this.dataList = dataList;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.recycler_view_item, null, false);
return new MyViewHolder(view, new OnRecyclerItemClickListener());
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
((MyViewHolder) holder).onRecyclerItemClickListener.updatePosition(position);
((MyViewHolder) holder).position.setText("" + position);
((MyViewHolder) holder).title.setText(dataList.get(position));
int valueToDisplay = 1;
if(positionToValueMap.containsKey(position)) {
valueToDisplay = positionToValueMap.get(position);
} else {
positionToValueMap.put(position, valueToDisplay);
}
((MyViewHolder) holder).valueView.setText("value: " + valueToDisplay);
}
#Override
public int getItemCount() {
return dataList.size();
}
private class MyViewHolder extends RecyclerView.ViewHolder {
private OnRecyclerItemClickListener onRecyclerItemClickListener;
private TextView position;
private TextView title;
private TextView valueView;
public MyViewHolder(View itemView, OnRecyclerItemClickListener onRecyclerItemClickListener) {
super(itemView);
itemView.setOnClickListener(onRecyclerItemClickListener);
this.onRecyclerItemClickListener = onRecyclerItemClickListener;
this.position = (TextView) itemView.findViewById(R.id.position);
this.title = (TextView) itemView.findViewById(R.id.title);
this.valueView = (TextView) itemView.findViewById(R.id.value_view);
}
}
private class OnRecyclerItemClickListener implements View.OnClickListener {
private int position = -1;
public void updatePosition(int position) {
this.position = position;
}
#Override
public void onClick(View v) {
int oldValue = positionToValueMap.get(position); // get current value
oldValue++; // increment
positionToValueMap.put(position, oldValue); // save current value
notifyItemChanged(position); // update clicked view so that it picks up the new saved value from the positionToValueMap in onBindViewHolder
}
}
}
RecyclerView item layout
<TextView
android:id="#+id/position"
android:layout_width="30dp"
android:layout_height="50dp"
android:textColor="#android:color/white"
android:gravity="center"
android:background="#android:color/holo_green_light"
android:layout_alignParentLeft="true"/>
<TextView
android:id="#+id/title"
android:layout_width="50dp"
android:layout_height="50dp"
android:textColor="#android:color/white"
android:gravity="center"
android:background="#android:color/holo_green_dark"
android:layout_toRightOf="#id/position" />
<TextView
android:id="#+id/value_view"
android:layout_width="match_parent"
android:layout_height="50dp"
android:textColor="#android:color/white"
android:gravity="center"
android:background="#android:color/holo_green_light"
android:layout_toRightOf="#id/title"
android:layout_alignParentRight="true"/>
</RelativeLayout>
And Activity to test it out
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
recyclerView.setAdapter(new MyAdapter(getApplicationContext(), getSampleData()));
}
private static List<String> getSampleData() {
List<String> dataList = new ArrayList<>();
dataList.add("zero");
dataList.add("one");
dataList.add("two");
dataList.add("three");
dataList.add("four");
dataList.add("five");
dataList.add("six");
dataList.add("seven");
dataList.add("eight");
dataList.add("nine");
dataList.add("ten");
dataList.add("eleven");
dataList.add("twelve");
dataList.add("thirteen");
dataList.add("fourteen");
dataList.add("fifteen");
dataList.add("sixteen");
dataList.add("seventeen");
dataList.add("eighteen");
dataList.add("nineteen");
dataList.add("twenty");
return dataList;
}
}
activity layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/root_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/white"/>
</RelativeLayout>