I have A listview, and in list view I have A textview. So this text view is visible in every item of listview. So when I click on any Textview then it's visibility mus be gone. But when I'll click on another textview then current must gone and previous must be visible.
In adapter class I tried a lot of things but I did't find the correct way. So how can I get this thing in getView().
holder.floorNo.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (holder.floorNo.getId() == v.getId()) {
final int position1 = listView
.getPositionForView((LinearLayout) v
.getParent());
} else {
}
}
});
Here position1 is the current position of click. Pleas help me.
You can set tag of textview as holder.settag(holder.floorNo). on click lister of floorNo get this tag by Textview floorno = (Textview) v.gettag();
Here you will get the clicked textview and add code for visible / invisible .
I don't know Which adapter you are using .If you are using CursorAdapter then in CursorAdapter by overridien method newView() it is possible
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
((TextView) (convertView
.findViewById(R.id.main_body_item_title_second_pics)))
.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
// do your stub here
}
});
}
You can use a textview class member as a "reminder" to know which textview is hidden, something like this :
private View mHiddenView = null
private int mFloorNoId = 0
....
....
holder.floorNo.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if(mHiddenView !=null&&mFloorNoId!=0){
// Show textview that was hidden
mHiddenView.findViewById(mFloorNoId).setVisibility(VISIBLE);
}
// Assign clicked view to hidden one and FloorNo id
mHiddenView = v;
mFloorNoId = holder.floorNo.getId();
// And hide it
mHiddenView.findViewById(mFloorNoId).setVisibility(GONE);
}
});
maintain a list of boolean in your adapter indicating visibility of TextView holder.floorNo.
boolean[] visibilityArray;
in constructor
visibilityArray; = new boolean[ no. Of Elements in your adapter ];
in getView() method
holder.floorNo.setVisibility(visibilityArray[position]);
holder.floorNo.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
notifyStateChange(position);
}
});
notifyStateChange(position) method defined as follows
private void notifyStateChange(int position) {
for(int i = 0; i<visibilityArray.length; i++){
visibilityArray[i] = true;
}
visibilityArray[position] = false;
this.notifyDataSetChanged();
}
Related
I'm experiencing a strange behavior with a horizontal scroll bar that I made with RecyclerView,
Hint:
I use SharedPreferences in onItemClick interface to transfer the position of clicked item to the fragment where I set the adapter , then I use another interface to transfer the clicked item position from the fragment to the activity where I set current item via viewpager.
Current behavior:
Issue #1
when an item gets selected the background (highlight) color is not changing, it has to be clicked again to get the highlight color.
Issue #2
When an item is clicked the scroll state resets to 1
Question :
why is this happening? and how to fix it?
Expected behavior
when an item is clicked I want the following behavior (single item selection)
RecyclerView adapter class
public class PlanetAdapter extends RecyclerView.Adapter<PlanetAdapter.PlanetViewHolder> {
public interface OnItemClickListener {
void onItemClick(PlanetModel item);
}
private ArrayList<PlanetModel> episodeslist;
private OnItemClickListener listener;
SharedPreferences getPref1x1 = getContext().getSharedPreferences("PlanetAdapter", Context.MODE_PRIVATE);
int pos1x1 = getPref1x1.getInt("position",0);
int isPlanetSelected=pos1x1;
public PlanetAdapter(ArrayList<PlanetModel> episodeslist, OnItemClickListener listener) {
this.episodeslist = episodeslist;
this.listener = listener;
}
#Override
public PlanetAdapter.PlanetViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v= LayoutInflater.from(parent.getContext()).inflate(R.layout.planet_row, parent,false);
PlanetViewHolder vh=new PlanetViewHolder(v);
return vh;
}
#Override
public void onBindViewHolder(PlanetAdapter.PlanetViewHolder vh, int position) {
TextView tv = (TextView) vh.itemView;
tv.setText(episodeslist.get(position).getPlanetName());
tv.setCompoundDrawablesWithIntrinsicBounds(R.drawable.bg, 0, 0, 0);
vh.bind(episodeslist.get(position), listener);
if (episodeslist.get(position).isPlanetSelected()) {
vh.itemView.setBackgroundColor(getContext().getResources().getColor(R.color.colorPrimaryDark));
}else{
vh.itemView.setBackgroundColor(getContext().getResources().getColor(R.color.colorPrimaryLight));
}
//holder.image.setImageResource(R.drawable.planetimage);
//vh.text.setText(episodeslist.get(position).toString());
}
#Override
public int getItemCount() {
return episodeslist.size();
}
public class PlanetViewHolder extends RecyclerView.ViewHolder{
protected TextView text;
public PlanetViewHolder(View itemView) {
super(itemView);
text= (TextView) itemView.findViewById(R.id.text_id);
}
public void bind(final PlanetModel item, final OnItemClickListener listener) {
itemView.setOnClickListener(new View.OnClickListener() {
#Override public void onClick(View v) {
int position = getPosition();
int previousItem = isPlanetSelected;
isPlanetSelected = position;
notifyItemChanged(previousItem);
notifyItemChanged(position);
SharedPreferences setPref = v.getContext().getSharedPreferences("PlanetAdapter", Context.MODE_PRIVATE);
setPref.edit().putInt("position", position).apply ();
listener.onItemClick(item);
//Toast.makeText(getContext(), "You have clicked " + item, Toast.LENGTH_SHORT).show();
//Toast.makeText(getContext(), "You have clicked " + ((TextView) itemView).getText(), Toast.LENGTH_SHORT).show();
}
});
}
}
}
The SharedPreference has a wrong-stored position value. To get the correct position within the ViewHolder, you need to use getBindingAdapterPosition() instead of getPosition.
Also you should update the value of the item before using listener.onItemClick(item);
Also you need to toggle the value of the selection boolean on the object before using notifyItemChanged() in order to reflect the change.
itemView.setOnClickListener(new View.OnClickListener() {
#Override public void onClick(View v) {
int position = getBindingAdapterPosition();
int previousItem = selectedPosition;
selectedPosition = position;
// Updating the selector boolean before notifying the changes to the adapter
PlanetModel currentSelectedItem = episodeslist.get(position);
currentSelectedItem.setPlanetSelected(true);
PlanetModel previousSelectedItem = episodeslist.get(previousItem);
previousSelectedItem.setPlanetSelected(false);
// Notify the changes to the adapter
notifyItemChanged(previousItem);
notifyItemChanged(position);
SharedPreferences setPref = v.getContext().getSharedPreferences("PlanetAdapter", Context.MODE_PRIVATE);
setPref.edit().putInt("position", position).apply ();
// Here you should define `item` before triggering the interface callback.
listener.onItemClick(item);
}
});
UPDATE:
The click listener should not be in the bind() as this is called from onBindViewHolder, you are iterating many listeners while you should only need one, to fix this, you need to transfer that to the holder constructor:
So, change the onBindViewHolder to:
#Override
public void onBindViewHolder(PlanetAdapter.PlanetViewHolder vh, int position) {
TextView tv = (TextView) vh.itemView;
tv.setText(episodeslist.get(position));
tv.setCompoundDrawablesWithIntrinsicBounds(R.drawable.bg, 0, 0, 0);
// setting the highlight color
if (episodeslist.get(position).isPlanetSelected()) {
vh.itemView.setBackgroundColor(getContext().getResources().getColor(R.color.colorPrimaryLight));
} else {
vh.itemView.setBackgroundColor(getContext().getResources().getColor(R.color.colorPrimaryDark));
}
}
And change the ViewHolder to:
public class PlanetViewHolder extends RecyclerView.ViewHolder{
protected TextView text;
public PlanetViewHolder(View itemView) {
super(itemView);
text= (TextView) itemView.findViewById(R.id.text_id);
itemView.setOnClickListener(new View.OnClickListener() {
#Override public void onClick(View v) {
int position = getAdapterPosition();
int previousItem = selectedPosition;
selectedPosition = position;
// Updating the selector boolean before notifying the changes to the adapter
PlanetModel currentSelectedItem = episodeslist.get(position);
currentSelectedItem.setPlanetSelected(true);
PlanetModel previousSelectedItem = episodeslist.get(previousItem);
previousSelectedItem.setPlanetSelected(false);
// Notify the changes to the adapter
notifyItemChanged(previousItem);
notifyItemChanged(position);
SharedPreferences setPref = v.getContext().getSharedPreferences("PlanetAdapter", Context.MODE_PRIVATE);
setPref.edit().putInt("position", position).apply ();
// Here you should define `item` before triggering the interface callback.
String item = episodeslist.get(position);
listener.onItemClick(item);
}
});
}
}
I have a ListView which implements a custom adapter that contains a few TextViews and two Buttons.
Now when i try to add an item to that ListView, if it is already in the list i want to change the text of its row's TextView (Quantity) and make it + 1. But i can't quite figure out how to interact with that particular TextView.
Adapter code:
public class ItemAdapter extends ArrayAdapter<Item> {
public ItemAdapter(#NonNull Context context) {
super(context, R.layout.lay_list_items);
}
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
LayoutInflater li = LayoutInflater.from(getContext());
View v = li.inflate(R.layout.lay_list_items, null);
final Item item = getItem(position);
TextView nom = (TextView)v.findViewById(R.id.txtNom);
TextView description = (TextView)v.findViewById(R.id.txtDescription);
final TextView qty = (TextView)v.findViewById(R.id.txtQty);
Button btnAjouter = (Button)v.findViewById(R.id.btnAjouter);
Button btnRetirer = (Button)v.findViewById(R.id.btnRetirer);
nom.setText(item.nom);
description.setText(item.description);
qty.setText("1");
btnAjouter.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int qtyCourante = Integer.parseInt(qty.getText().toString());
int newQty = qtyCourante + 1;
qty.setText(Integer.toString(newQty));
}
});
btnRetirer.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int qtyCourante = Integer.parseInt(qty.getText().toString());
int newQty = qtyCourante - 1;
if (newQty > 0)
qty.setText(Integer.toString(newQty));
else
ItemAdapter.super.remove(item);
}
});
return v;
}
You need to save the count, and then use it.
Use ArrayList<Integer> or add one more field int count in your Model Class Item. It is better to add one more field in Item class.
Initialize it as 1 for all items.
And use the code,
qty.setText(String.valueOf(item.getCount()));//declare a method to get count field value, here getCount()
In your button click,
btnAjouter.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
item.setCount( item.getCount() + 1 ); //declare a method to set value
notifyDataSetChanged();
}
});
And also
btnRetirer.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if ( item.getCount() > 0)
item.setCount( item.getCount() - 1 );
else
ItemAdapter.super.remove(item);
notifyDataSetChanged();
}
});
notifyDataSetChanged(); should be invoked to update your changes.
Since you are using an ArrayAdapter as your base Class, if you want to add a new item, you can just call:
adapter.add(newItem);
adapter.notifyDataSetChanged();
and the adapter will help you handle the new item.
I am designing a chess Board application and I am using a gridview for storing 64 buttons and assigning id to them starting from 0 to 63. But the ids are starting from 2 instead of 0, I can't understand why that is happening.
I am using ButtonAdapter class I made and the following is its getView() method and I set text of each button same as its id to make sure they are getting correct ids.
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
Button button;
if(view == null){
button = new Button(mContext);
}else{
button = (Button)view;
}
button.setId(mIndex);
button.setText(button.getId()+"");
button.setTextSize(5);
button.setPadding(0,0,0,0);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(mContext, view.getId()+"", Toast.LENGTH_SHORT).show();
}
});
mIndex++;
return button;
}
mIndex is initialized to 0 in my constructor like following
private Context mContext;
private int mIndex;
public ButtonAdapter(Context context){
mContext = context;
mIndex = 0;
}
and the screenshot of result I am getting is below
Please help, I am a beginner. Sorry for any mistakes, thanks in advance.
Don't use mIndexvariable and increment because it will create issue when you will scroll.
You can use adapter position instead of mIndex.
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
Button button;
if(view == null){
button = new Button(mContext);
}else{
button = (Button)view;
}
button.setId(i);
button.setText(String.valueOf(i));
button.setTextSize(5);
button.setPadding(0,0,0,0);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(mContext, view.getId()+"", Toast.LENGTH_SHORT).show();
}
});
return button;
}
you can set the tag like this
button.setTag(Integer.valueOf(position));
and get that id by
Integer position = (Integer)view.getTag();
This is in the inside of a BaseAdapter that gets called in a Fragment. The OnClickListener should remove the hole adapteritem but for some reason it only removes the content but it won't remove the frame. It allways keeps the size of the adapter just the content disapears, the underlining stays too.
public View getView(final int position, View convertView, ViewGroup parent) {
boolean memCache = true;
boolean fileCache = true;
if (convertView == null) {
LayoutInflater mInflater = (LayoutInflater)
activity.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
convertView = mInflater.inflate(R.layout.favorite_list_item, null);
}
TextView txtTitle = (TextView) convertView.findViewById(R.id.title);
txtTitle.setText(allFavorite.get(position).getTitle());
Button deleteButton = (Button) convertView.findViewById(R.id.delete_button);
deleteButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
((View) view.getParent()).setVisibility(View.GONE);
}
});
return convertView;
}
}
You should remove the data bind to your view from your data set and call a notifyDataSetChanged() afterward rather than hide the view itself.
Button deleteButton = (Button) convertView.findViewById(R.id.delete_button);
deleteButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
allFavorite.remove(position);
notifyDataSetChanged();
}
});
try like this,
deleteButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
adapter.remove(adapter.getItem(position));
}
});
hope it will help you
Your code just make view invisible, not delete them. You have to delete from adapter like this :
listItem.remove(position);
adapter.notifyDataSetChanged();
I am very new to Java and have encountered a problem. I have set up a TextView and want to call the setText method when a button is clicked from my dialog. This TextView is set up in my main activity. I have not initialized it as static as this produces an error. The line of code in question is - Tabs.total.setText("PRINTING TO TEXT VIEW"); I want this to set the content of my TextView defined in my class Tabs.
Variable total is defined like this -
TextView total = (TextView) findViewById(R.id.total_view);
I have looked a lot for some material on this problem but have failed to find a solution so far. I hope somebody can help. Thanks!!
public View getView(final int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
final View v;
if(convertView==null){
LayoutInflater li = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = li.inflate(R.layout.scrollergrid, null);
final TextView tv = (TextView)v.findViewById(R.id.icon_text);
tv.setTag(pos);
tv.setText(mItems[pos]);
TextView price = (TextView)v.findViewById(R.id.price_text);
price.setText("$" + Prices[pos]);
pos += 1;
final ImageView iv = (ImageView)v.findViewById(R.id.icon_image);
iv.getLayoutParams().height = 150;
iv.getLayoutParams().width = 150;
iv.setScaleType(ImageView.ScaleType.CENTER_CROP);
iv.setImageResource(mThumbIds[position]);
iv.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
id = tv.getTag();
System.out.println(mItems[(Integer) id] + " $" + Prices[(Integer) id]);
final Dialog dialog = new Dialog(mContext);
dialog.setContentView(R.layout.alertdialog);
dialog.setTitle(mItems[(Integer) id]);
ImageView dialogImage = (ImageView) dialog.findViewById(R.id.alert_image);
dialogImage.setImageResource(mThumbIds[(Integer) id]);
TextView itemDescription = (TextView) dialog.findViewById(R.id.item_description);
itemDescription.setText("A nice little piece of food. Good for all the family. Full of flavour!!");
TextView itemPrice = (TextView) dialog.findViewById(R.id.item_price);
itemPrice.setText("$" + Prices[(Integer) id]);
Button goBack = (Button) dialog.findViewById(R.id.go_back);
goBack.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
dialog.cancel();
}
});
Button order = (Button) dialog.findViewById(R.id.order);
order.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Tabs.Order.add(mItems[(Integer) id] + " " + Prices[(Integer) id]);
System.out.println(Tabs.Order);
Tabs.total.setText("HIIII");
dialog.cancel();
}
});
dialog.show();
}
});
}
else
{
v = convertView;
}
return v;
}
}
I think what you want to do is make your own onClickListener().
Check out this solution: How to pass parameters to OnClickListener?
And just pass in your TextView to the constructor.
You have two problems:
Using static variables for storing views is not recommended at all (memory leaks). You should simply put the reference either as a parameter to the function or as a field.
On the "else" part, you didn't update the variable "v" to have the new data being shown, only upon creation of the view you put data into it.