Hello at all the community,
i've this adapter with 2 button and 2 textview.
#Override
public View getView(int position, View view, ViewGroup parent) {
if(view == null) {
holder = new Holder();
inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.my_adapter, null);
holder.result = (TextView)view.findViewById(R.id.description);
holder.value = (TextView)view.findViewById(R.id.value);
holder.add = (Button)view.findViewById(R.id.add);
holder.subtract = (Button)view.findViewById(R.id.subtract);
myObject = getItem(position);
holder.result.setText(myObject.result);
holder.value.setText(myObject.value);
view.setTag(holder);
} else {
holder = (Holder)view.getTag();
}
holder.add.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
// TODO Auto-generated method stub
}
});
return view;
}
Now my question is: if I want that when the user press on add button set the text of the textview with (for example) 5 how can i do this? If I put into the onCLick method
holder.result.setText("My text") set the text of the last textview and not the correspond textview of the selected row item (I disabled the click on the listview with):
#Override
public boolean isEnabled(int position) {
return false;
}
Is there any solution for my problem?
You should put your code in the getView method inside the adapter and remember to use references to the current Button/TextVeiw so that each Button would correspond to that specific TextView
P.S. I found something with your code check this out:
#Override
public View getView(int position, View view, ViewGroup parent) {
if(view == null) {
holder = new Holder();
inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.my_adapter, null);
holder.result = (TextView)view.findViewById(R.id.description);
holder.value = (TextView)view.findViewById(R.id.value);
holder.add = (Button)view.findViewById(R.id.add);
holder.subtract = (Button)view.findViewById(R.id.subtract);
view.setTag(holder);
} else {
holder = (Holder)view.getTag();
}
myObject = getItem(position);
holder.result.setText(myObject.result);
holder.value.setText(myObject.value);
final TextView tv = holder.result;
holder.add.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
tv.setText("bla bla");
}
});
return view;
}
You mixed something up, the getItem has to be below the view creation stuff. First create the view, then set the values.
#Override
public View getView(int position, View view, ViewGroup parent) {
if(view == null) {
holder = new Holder();
inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.my_adapter, null);
holder.result = (TextView)view.findViewById(R.id.description);
holder.value = (TextView)view.findViewById(R.id.value);
holder.add = (Button)view.findViewById(R.id.add);
holder.subtract = (Button)view.findViewById(R.id.subtract);
view.setTag(holder);
} else {
holder = (Holder)view.getTag();
}
myObject = getItem(position);
holder.result.setText(myObject.result);
holder.value.setText(myObject.value);
holder.add.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
//What should happen here?
}
});
return view;
}
Related
Can you help me out, I'm learning! ;-)
I have two buttons "+" and "-" and I want them to increase or decrease the amount by one up or one down. How do I make sure that it will only have effect on the right textview using an adapter.
Now all the buttons only effects the first one. I know I have to get the position/id of the array. But I don't know how.
btw
Merk = Brand
Aantal = Amount
public class ListViewDemo2 extends Activity {
private ArrayList<String> data = new ArrayList<String>();
int aantal = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_view_demo2);
ListView lv = (ListView) findViewById(R.id.bestel_lijst);
lv.setAdapter(new MyListAdapter(this, R.layout.list_item, data));
generateListContent();
}
private void generateListContent(){
for (int i =0; i < 55; i++){
data.add("this is row number: " + i);
}
}
#Override
public boolean onCreateOptionsMenu (Menu menu){
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings){
return true;
}
return super.onOptionsItemSelected(item);
}
private class MyListAdapter extends ArrayAdapter<String>{
private int layout;
public MyListAdapter(Context context, int resource, List<String> objects) {
super(context, resource, objects);
layout = resource;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder mainViewholder = null;
if(convertView == null){
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(layout, parent, false);
ViewHolder viewHolder = new ViewHolder();
viewHolder.Merk = (TextView) convertView.findViewById(R.id.Merk);
viewHolder.Aantal = (TextView) convertView.findViewById(R.id.Aantal);
viewHolder.btnup = (Button) convertView.findViewById(R.id.Bup);
viewHolder.btndown = (Button) convertView.findViewById(R.id.Bdown);
viewHolder.btndown.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v){
aantal = aantal-1;
displayAantal(aantal);
}
});
viewHolder.btnup.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v){
aantal = aantal+1;
displayAantal(aantal);
}
});
convertView.setTag(viewHolder);
}
else {
mainViewholder = (ViewHolder)convertView.getTag();
mainViewholder.Merk.setText(getItem(position));
}
return convertView;
}
}
public class ViewHolder {
TextView Merk;
TextView Aantal;
Button btnup;
Button btndown;
}
public void displayAantal(int aantal) {
TextView aantalView = (TextView) findViewById(R.id.Aantal);
aantalView.setText(String.valueOf(aantal));
}
}
your problem seems to be in your displayAantal(int) method, in particular, in this line:
TextView aantalView = (TextView) findViewById(R.id.Aantal);
You do not need to re-initialize that field here, since it is already initialized inside getView():
viewHolder.Aantal = (TextView) convertView.findViewById(R.id.Aantal);
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder mainViewholder = null;
if(convertView == null){
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(layout, parent, false);
ViewHolder viewHolder = new ViewHolder();
viewHolder.Merk = (TextView) convertView.findViewById(R.id.Merk);
viewHolder.Aantal = (TextView) convertView.findViewById(R.id.Aantal);
viewHolder.btnup = (Button) convertView.findViewById(R.id.Bup);
viewHolder.btndown = (Button) convertView.findViewById(R.id.Bdown);
convertView.setTag(viewHolder);
}
else {
mainViewholder = (ViewHolder)convertView.getTag();
}
String str = getItem(position);
mainViewholder.Merk.setText(str);
viewHolder.btndown.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v){
//just handle the data ,then call adapter.notifyDataSetChanged();
}
});
viewHolder.btnup.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v){
//just handle the data ,then call adapter.notifyDataSetChanged();
}
});
return convertView;
}
I have a listview item with a label and two buttons. I tried to change the label on button click. But it's changing text on another listview item. Not the label with button. I did this using a custom list adapter. I tried it like following,
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final MenuItem listItem = objects.get(position);
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) this.context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.menu_list_item, null);
btnPlus = (ButtonRectangle) convertView.findViewById(R.id.buttonPlus);
btnPlus.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int i = 0;
cartQtyTextView.setText("" + ++i);
}
});
}
}
How may I fix this?
You might want to create holder.
I didn't include your menu item code due to i didn't see you got use it.
public class Holder {
ButtonRectangle buttonPlus;
TextView cartQtyTextView;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// Get Holder
final Holder holder = new Holder();
// Change Layout
LayoutInflater inflater = (LayoutInflater) this.context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.menu_list_item, null);
// Find Control
holder.buttonPlus = (ButtonRectangle)view.findViewById(R.id.buttonPlus);
holder.cartQtyTextView = (TextView)view.findViewById(R.id.cartQtyTextView);
// Check & Set
if (holder.buttonPlus != null) {
holder.buttonPlus.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int i = 0;
if (holder.cartQtyTextView != null) {
holder.cartQtyTextView.setText("" + ++i);
}
}
});
}
return view;
}
This is because you are setting the listener inside the if(convertView==null).
So the listener is only set once a view is created, but when you scroll, the list view is reusing a hidden item, but it keep the first assigned listener since the convertView is not null.
You need to set your onClickListener outside the if. And it is better if you use a holder for better performances
public class ExampleAdapter extends ArrayAdapter<MenuItem> {
private Activity activity;
private int resource;
private List<MenuItem> objects;
public ExampleAdapter(Activity activity, int resource, List<MenuItem> objects) {
super(activity, resource, objects);
this.activity = activity;
this.resource = resource;
this.objects= objects;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
MenuItem listItem = objects.get(position);
ViewHolder holder = null;
if (convertView == null) {
holder = new ViewHolder();
LayoutInflater li = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = li.inflate(resource, parent, false);
holder.labelTextView= (TextView) convertView.findViewById(R.id.labelTextView);
holder.btnPlus= (ButtonRectangle) convertView.findViewById(R.id.buttonPlus);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.btnPlus.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int i = 0;
holder.labelTextView.setText("" + ++i);
}
});
return convertView;
}
static class ViewHolder {
TextView labelTextView;
ButtonRectangle btnPlus;
}
}
When I click the GridView item multiple checks appear where I just want it to appear in the one. I'm pretty sure this has something to do with the recycled views, but I am not sure how to prevent it from happening. Any advice is appreciated.
grid.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
final int position, long id) {
ImageView check = (ImageView) view.findViewById(R.id.check);
if (check.getVisibility() == View.GONE) {
check.setVisibility(View.VISIBLE);
I
}
else {
check.setVisibility(View.GONE);
}
}
});
Here is the adapter
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View grid;
LayoutInflater inflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
grid = new View(mContext);
grid = inflater.inflate(R.layout.grid_item, null);
} else {
grid = (View) convertView;
}
ImageView imageView = (ImageView) grid.findViewById(R.id.grid_image);
final ProgressBar pb = (ProgressBar) grid.findViewById(R.id.progressbar);
final ImageView check = (ImageView) grid.findViewById(R.id.check);
Ion.with(mContext).load(objects.get(position).getThumnailURL())
.progressBar(pb).withBitmap()
.error(R.drawable.ic_launcher).intoImageView(imageView).setCallback(new FutureCallback<ImageView>() {
#Override
public void onCompleted(Exception e, ImageView file) {
pb.setVisibility(View.GONE);
}
});
return grid;
}
You can do it like this:
put a boolean variable in your object that is passed to your adapter(ArrayList) and control the visibility of check boxes by this variable so if onitemclick is called toggle that variable and call notifydatasetchange. In the getView set each check boxes by the value of this variable. in this way if you scroll the gridview your value of your check boxes do not get lost.
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
ViewHolder _holder = new ViewHolder();
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = inflater.inflate(R.layout.grid_item, null);
_holder.imageView = (ImageView) grid.findViewById(R.id.grid_image);
_holder.pb = (ProgressBar) grid.findViewById(R.id.progressbar);
_holder.check = (ImageView) grid.findViewById(R.id.check);
convertView.setTag(_holder);
}
else {
_holder = (ViewHolder) convertView.getTag();
}
//here set your values
Ion.with(mContext).load(objects.get(position).getThumnailURL())
.progressBar(pb).withBitmap()
.error(R.drawable.ic_launcher).intoImageView(imageView).setCallback(new FutureCallback<ImageView>() {
#Override
public void onCompleted(Exception e, ImageView file) {
pb.setVisibility(View.GONE);
}
});
return grid;
}
class ViewHolder {
ImageView imageView,check;
ProgressBar pb;
}
Try this !!
When i am scrolling ListView position of the item changes.My ListView contain 2 Button and 2 TextView. These 2 Button are initially invisible. when user Long click on item i just set the visibility.Its working but when i scroll the ListView ,it changes the position.Why?
I am setting this visibility and invisibility code inside of my adapter class..
here is my code :::
#Override
public View getView(int position, View convertView, ViewGroup parent) {
holder = new ViewHolder();
if (convertView == null) {
convertView = lInflater.inflate(R.layout.message_row, null);
holder.messageDeleteButton = (Button) convertView
.findViewById(R.id.delete_button);
holder.messageTextView = (TextView) convertView
.findViewById(R.id.message);
holder.timeTextView = (TextView) convertView
.findViewById(R.id.time);
holder.copyMessageButton = (ImageButton) convertView
.findViewById(R.id.copy_bt);
holder.messageDeleteButton
.setOnClickListener(new OnClickListener() {
#Override
public void onClick(final View v) {
System.out.println("Delete clicked");
}
});
convertView.setTag(R.layout.message_row, holder);
} else {
holder = (ViewHolder) convertView.getTag(R.layout.message_row);
}
convertView.setTag(position);
holder.messageDeleteButton.setTag(position);
if (mMessageData.get(position).isVisible())
holder.messageDeleteButton.setVisibility(View.VISIBLE);
else
holder.messageDeleteButton.setVisibility(View.GONE);
holder.messageTextView.setText(mMessageData.get(position)
.getMessage_text());
holder.messageTextView.setTypeface(Typeface.createFromAsset(
mContext.getAssets(), "Existence-Light.ttf"));
holder.timeTextView.setText(mMessageData.get(position)
.getMessage_date());
holder.timeTextView.setTypeface(Typeface.createFromAsset(
mContext.getAssets(), "Existence-Light.ttf"));
convertView.setOnTouchListener(mOnTouchListener);
convertView.setOnClickListener(mOnClickListener);
// convertView.setOnLongClickListener(mLongClick);
return convertView;
}
This is my OnTouchListiner code it will working fine.But when i scroll the ListView the buttons positions will changed..
class MyTouchListener implements OnTouchListener {
#SuppressWarnings("deprecation")
private final GestureDetector gestureDetector = new GestureDetector(
new GestureListener());
#Override
public boolean onTouch(View v, MotionEvent event) {
int touch = 0;
ViewHolder holder = (ViewHolder) v.getTag(R.layout.message_row);
animation = new Animater();
int action = event.getAction();
int position = (Integer) v.getTag();
pos = position;
view = v;
switch (action) {
case MotionEvent.ACTION_DOWN:
action_down_x = (int) event.getX();
Log.d("action", "ACTION_DOWN - ");
touch = 0;
break;
case MotionEvent.ACTION_MOVE:
Log.d("action", "ACTION_MOVE - ");
action_up_x = (int) event.getX();
difference = action_down_x - action_up_x;
calcuateDifference(holder, position);
touch = 1;
break;
case MotionEvent.ACTION_UP:
Log.d("action", "ACTION_UP - ");
// calcuateDifference(holder, position);
action_down_x = 0;
action_up_x = 0;
difference = 0;
// touch = 2;
break;
}
return gestureDetector.onTouchEvent(event);
}
public GestureDetector getGestureDetector() {
return gestureDetector;
}
}
In this gestuer class when i tap on ListView just display one more Button.This also be changed the position
public class GestureListener extends SimpleOnGestureListener{
#SuppressLint("NewApi")
#Override
public void onLongPress(MotionEvent e) {
// TODO Auto-generated method stub
super.onLongPress(e);
final ViewHolder hold = (ViewHolder) view.getTag(R.layout.message_row);
hold.copyMessageButton.setVisibility(View.VISIBLE);
hold.copyMessageButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
System.out.println("hello you click me..");
});
}
}
What is the wrong on my code..Any one please help me...
Android ListView use Adapters to recycle views that's why ListView position changes while scrolling to conserve memory.See the Google I/O presentation given by Romain Guy to understand how adapters work. http://www.youtube.com/watch?v=N6YdwzAvwOA
Also check the below links,
http://strangevikas.wordpress.com/tag/how-adapter-works-in-android-android-and-adapters/
http://www.edureka.in/blog/what-are-adapters-in-android/
You just need to do some modification in your code like:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = new ViewHolder();
if (convertView == null) {
convertView = lInflater.inflate(R.layout.message_row, null);
holder.messageDeleteButton = (Button) convertView
.findViewById(R.id.delete_button);
holder.messageTextView = (TextView) convertView
.findViewById(R.id.message);
holder.timeTextView = (TextView) convertView
.findViewById(R.id.time);
holder.copyMessageButton = (ImageButton) convertView
.findViewById(R.id.copy_bt);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.messageDeleteButton.setTag(mMessageData.get(position));
holder.messageDeleteButton
.setOnClickListener(new OnClickListener() {
#Override
public void onClick(final View v) {
// message data can be retrieved here like
MessageData mData = (MessageData) v.getTag();
System.out.println("Delete clicked");
}
});
if (mMessageData.get(position).isVisible())
holder.messageDeleteButton.setVisibility(View.VISIBLE);
else
holder.messageDeleteButton.setVisibility(View.GONE);
holder.messageTextView.setText(mMessageData.get(position)
.getMessage_text());
holder.messageTextView.setTypeface(Typeface.createFromAsset(
mContext.getAssets(), "Existence-Light.ttf"));
holder.timeTextView.setText(mMessageData.get(position)
.getMessage_date());
holder.timeTextView.setTypeface(Typeface.createFromAsset(
mContext.getAssets(), "Existence-Light.ttf"));
return convertView;
}
How can I display text in TextView at get view after this call
ListAdapter adapter = new MyCustomAdapter (
ManageSection.this, studentList,
R.layout.list_student, new String[] { TAG_StudentID,
TAG_StudentNo,TAG_FullName},
new int[] { R.id.StudentID, R.id.StudentNo,R.id.FullName});
setListAdapter(adapter);
and the class MyCustomAdapter has a get view, I will display the text
holder.FullName= (TextView) convertView.findViewById(R.id.FullName);
holder.FullName.setText();
holder.StudentNo=(TextView) convertView.findViewById(R.id.StudentNo);
holder.StudentNo.setText();
So at set text what should I write cause I do
no=student.get(holder.position).get(TAG_StudentNo);
name =student.get(holder.position).get(TAG_FullName);
and take no, name but the text is duplicated in the whole list
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if(convertView==null)
{
LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = mInflater.inflate(resource, parent, false);
holder = new ViewHolder();
no=student.get(holder.position).get(TAG_StudentNo);
name =student.get(holder.position).get(TAG_FullName);
holder.StudentID= (TextView) convertView.findViewById(R.id.StudentID);
holder.FullName= (TextView) convertView.findViewById(R.id.FullName);
holder.FullName.setText();
holder.StudentNo=(TextView) convertView.findViewById(R.id.StudentNo);
holder.StudentNo.setText();
holder.DeleteStudent = (ImageView) convertView.findViewById(R.id.DeleteStudent);
holder.AlertIcon = (ImageView) convertView.findViewById(R.id.Alert);
// add a listener for phone call
holder.DeleteStudent.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
id = student.get(holder.position).get(TAG_StudentID);
Toast.makeText(getContext(),id,Toast.LENGTH_LONG).show();
}
});
holder.AlertIcon.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// String email = MyCustomAdapter.listMap.get(holder.position).get("email");
// ActivityHelper.startActivity(ActivityManager.EMAIL, email);
}
});
convertView.setTag(holder);
}
else
{
holder = (ViewHolder) convertView.getTag();
}
holder.position = position;
return convertView;
}
private static class ViewHolder
{
ImageView DeleteStudent;
ImageView AlertIcon;
TextView StudentID, StudentNo ,FullName;
int position;
}
}
Can anyone tell me what the problem is here?
Try this code.
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if(convertView==null)
{
LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = mInflater.inflate(resource, parent, false);
holder = new ViewHolder();
convertView.setTag(holder);
}
else
{
holder = (ViewHolder) convertView.getTag();
}
holder.position = position;
no=student.get(holder.position).get(TAG_StudentNo);
name =student.get(holder.position).get(TAG_FullName);
holder.StudentID= (TextView) convertView.findViewById(R.id.StudentID);
holder.FullName= (TextView) convertView.findViewById(R.id.FullName);
holder.FullName.setText();
holder.StudentNo=(TextView) convertView.findViewById(R.id.StudentNo);
holder.StudentNo.setText();
holder.DeleteStudent = (ImageView) convertView.findViewById(R.id.DeleteStudent);
holder.AlertIcon = (ImageView) convertView.findViewById(R.id.Alert);
// add a listener for phone call
holder.DeleteStudent.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
id = student.get(holder.position).get(TAG_StudentID);
Toast.makeText(getContext(),id,Toast.LENGTH_LONG).show();
}
});
holder.AlertIcon.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// String email = MyCustomAdapter.listMap.get(holder.position).get("email");
// ActivityHelper.startActivity(ActivityManager.EMAIL, email);
}
});
return convertView;
}
private static class ViewHolder
{
ImageView DeleteStudent;
ImageView AlertIcon;
TextView StudentID, StudentNo ,FullName;
int position;
}
}
What you were doing is just setting the data only when the convertView is null and if not you just returning the view after some Holder operation. You need to set Text etc, in the textView in every case. If you need more explanation, please ask.
its simple buddy U just have to put this line instead of blank setText()
no=student.get(holder.position).get(TAG_StudentNo);// the roll_number string
name =student.get(holder.position).get(TAG_FullName);//full name string
holder.StudentID= (TextView) convertView.findViewById(R.id.StudentID);
holder.FullName= (TextView) convertView.findViewById(R.id.FullName);
holder.FullName.setText(name);//pass fullname
holder.StudentNo=(TextView) convertView.findViewById(R.id.StudentNo);
holder.StudentNo.setText(no);//pass roll no.
you just have to pass the no and 'namevariable tosetText()` method.