I have this code inside my BaseAdapter Adapter:
public View getView(final int position, View convertView, ViewGroup parent) {
View vi=convertView;
if(convertView==null)
vi = inflater.inflate(R.layout.facebook_friends_layout, null);
TextView friendsName = (TextView)vi.findViewById(R.id.tvFacebookName); // Friends thumb
friend_image=(ImageView)vi.findViewById(R.id.ivFacebookPicture); // thumb image
song= new HashMap<String, String>();
song = data.get(position);
friendsName.setText(song.get(MyFriends.KEY_FBNAME));
//Log.i("Facebook Pangalan", ""+MyFriends.KEY_FBNAME);
FriendName = (String) friendsName.getText().toString();
FBID = song.get(MyFriends.KEY_FBID);
String fbAvatarUrl = "http://graph.facebook.com/"+ FBID +"/picture";
//Log.i("FBID", FBID);
BitmapManager.INSTANCE.loadBitmap(fbAvatarUrl, friend_image, 100,100);
Button btn=(Button)vi.findViewById(R.id.btnAdd);
if (FBID.equals(""))
{
btn.setVisibility(View.GONE);
}
else
{
btn.setVisibility(View.VISIBLE);
}
btn.setOnClickListener(new OnClickListener(){
public void onClick(View arg0) {
LOCK_BASEDATA = MyFriends.LOCK_BASEDATA;
if (LOCK_BASEDATA.equals("0"))
{
//FACEBOOK FRIENDS
Log.i("", ""+FriendName);
//AddfromFacebookFriends();
}
else if (LOCK_BASEDATA.equals("1"))
{
//MY REQUEST
//((MyFriends)context).SetMyRequest();
//Log.i("LangYa", "Langya");
}
else if (LOCK_BASEDATA.equals("2"))
{
//FRIEND REQUEST
//((MyFriends)context).SetFriendRequest();
//d2papasok
AddFriendRequest();
}
}
});
return vi;
}
I am logging my friend's name whenever I click on the button. Now my problem starts when I click the button; I am not getting my desired string. It is getting the string from another row of my listview.
EDIT
Thanks, actually ive just aaded this code
public void onClick(View arg0) {
LOCK_BASEDATA = MyFriends.LOCK_BASEDATA;
if (LOCK_BASEDATA.equals("0"))
{
//Object x =btn.getTag();
//String sa = x.toString();
View parentView = (View) arg0.getParent();
String textviewtext = ((TextView) parentView.findViewById(R.id.hiddentv)).getText().toString();
//FACEBOOK FRIENDS
AddfromFacebookFriends(textviewtext);
}
else if (LOCK_BASEDATA.equals("1"))
{
I am just getting my parents View to get my desired textview and now it works. Thanks anyway
You are trying to get the FriendName using this code:
TextView friendsName = (TextView)vi.findViewById(R.id.tvFacebookName);
FriendName = (String) friendsName.getText().toString();
This is not The FriendName of the ListView item you clicked. Its the FriendName of the newly created ListView item. Because in getView(), the ListView item you get is the newly created one.
One way to solve this is:
Use tags like KunalK suggested. I am not sure if it works...i never tried it.
Or the other way is:
onButtonClicked get the Position of the ListView item you clicked, and get the respective Name from the ArrayList you are using.
Here the Position is not the position parameter in the getView(). That gives the position of the newly created ListView item again.
Use this to get the actual position of the clicked item:
int clickedItemPosition = yourListView.getPositionForView((View) yourButton.getParent());
you should go with this by setting the "FriendName" in your button's setTag property. and whenever you handle your button click event fetch your FriendName String by using getTag property of button. for e.g. something like this:
....
btn.setTag(FriendName);
btn.setOnClickListener(new OnClickListener(){
public void onClick(View arg0) {
LOCK_BASEDATA = MyFriends.LOCK_BASEDATA;
if (LOCK_BASEDATA.equals("0"))
{
//FACEBOOK FRIENDS
Log.i("", ""+btn.getTag().toString());
//AddfromFacebookFriends();
}
else if (LOCK_BASEDATA.equals("1"))
{
//MY REQUEST
//((MyFriends)context).SetMyRequest();
//Log.i("LangYa", "Langya");
}
else if (LOCK_BASEDATA.equals("2"))
{
//FRIEND REQUEST
//((MyFriends)context).SetFriendRequest();
//d2papasok
AddFriendRequest();
}
}
});
....
Getting the name from the list can be accompished by using an onListItemClick method as follows (not in your adapter, but in the class with your list):
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
TextView friendsName = (TextView)v.findViewById(R.id.tvFacebookName);
FriendName = (String) friendsName.getText().toString();
}
Since this code is the onListItemClick method, the View v parameter is the view of the row you clicked. Once you have that, you search that particular row view for the TextView you want and then pull the string from that.
You had the right idea, you just put it in the wrong place.
Related
I googled alot for this with no result. I have a custom ListView, every element has few TextViews and 3 Spinners and button. When I set values on spinners and press a button I want to get selcted values from those spinners and send them to a server. Everything works fine for list elements from top to the last visible element but on items that are not visible or visible in half 2 bad things happen.
If I change value on spinner, press button to save, 2 things happen depedning on which element I work on:
If element was half, or a little visible on activity load and I do those steps on it the value that is passed is the value that was set before I changed it.
If element wasn't visible at all and I do steps on it app crashes with NullPointerException linking the error to the declaration of a Spinner.
Code:
Adapter:
public View getView(final int position, View convertView, final ViewGroup parent) {
StudentList students = studentList.get(position);
LayoutInflater inflater = (LayoutInflater) context.getSystemService(LAYOUT_INFLATER_SERVICE);
final View view = inflater.inflate(R.layout.student_list, null);
TextView id = (TextView) view.findViewById(R.id.list_id);
TextView name = (TextView) view.findViewById(R.id.list_name);
TextView surname = (TextView) view.findViewById(R.id.list_surname);
Spinner t1 = (Spinner) view.findViewById(R.id.list_t1);
Spinner t2 = (Spinner) view.findViewById(R.id.list_t2);
Spinner t3 = (Spinner) view.findViewById(R.id.list_t3);
TextView final = (TextView) view.findViewById(R.id.list_final);
Button save = (Button) view.findViewById(R.id.save);
id.setText(students.getId());
name.setText(students.getName());
surname.setText(students.getSurname());
final.setText(students.getFinal());
for (int i=0;i<t1.getCount();i++){
if (t1.getItemAtPosition(i).toString().equalsIgnoreCase(students.getT1())){
t1.setSelection(i);
}
}
for (int i=0;i<t2.getCount();i++) {
if (t2.getItemAtPosition(i).toString().equalsIgnoreCase(students.getT2())) {
t2.setSelection(i);
}
}
for (int i=0;i<t3.getCount();i++){
if (t3.getItemAtPosition(i).toString().equalsIgnoreCase(students.getT3())){
t3.setSelection(i);
}
}
if(t1.getSelectedItemPosition() > 1){
t2.setEnabled(false);
t3.setEnabled(false);
} else if (t2.getSelectedItemPosition() > 1){
t3.setEnabled(false);
}
save.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
((ListView) parent).performItemClick(v, position, 0);
}
});
if(studentList.get(position).getProtokol().equals("open")){
} else {
t1.setEnabled(false);
t2.setEnabled(false);
t3.setEnabled(false);
save.setEnabled(false);
}
return view;
}
onCreate:
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
long viewId = view.getId();
Spinner t1 = (Spinner) parent.getChildAt(position).findViewById(R.id.lista_termin1);//There the app crashes if I do things I described above
Spinner t2 = (Spinner) parent.getChildAt(position).findViewById(R.id.lista_termin2);
Spinner t3 = (Spinner) parent.getChildAt(position).findViewById(R.id.lista_termin3);
if (viewId == R.id.save) {
String t1Itemn = t1.getSelectedItem());
String t2Itemn = t2.getSelectedItem());
String t3Itemn = t3.getSelectedItem());
//Code that sends those string to the server based on urlConnection - works perfectly fine)
}
}
});
I was googling for 2 days and finally decided to post here, but 1h later I found the solution here. Changed all spinners like this:
Spinner t1 = (Spinner) parent.getChildAt(position-parent.parent.getFirstVisiblePosition()).findViewById(R.id.lista_termin1);
I have implemented a list View with CheckedTextView . When I am selecting a particular row and clicking on checkbox then checkbox becomes invisible. Also sometimes any other row get selected.I want to select multiple items.
please help...
List_row Layout is..
<CheckedTextView
android:id="#+id/service_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="TextView"
android:textSize="20sp"
android:layout_marginBottom="10dp"
android:checkMark="?android:attr/listChoiceIndicatorMultiple"
android:textColor="#000000"
android:checked= "false"
>
CustomListView is:
import java.util.ArrayList;
public class CustomListView extends ArrayAdapter {
//to reference the Activity
private final Activity context;
String value;
//to store the list items
private final String[] nameArray;
CheckedTextView nameTextField;
public CustomListView(Activity context, ArrayList nameArra) {
super(context, R.layout.row_list_view, nameArrayParam);
this.context = context;
this.nameArray = nameArrayParam;
}
public View getView(int position, View view, ViewGroup parent)
{
LayoutInflater inflater = context.getLayoutInflater();
View rowView = inflater.inflate(R.layout.row_list_view, null, true);
//this code gets references to objects in the listview_row.xml file
nameTextField = (CheckedTextView)
rowView.findViewById(R.id.service_name);
//this code sets the values of the objects to values from the arrays
nameTextField.setText(nameArray[position]);
// perform on Click Event Listener on CheckedTextView
nameTextField.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.v("customList",";clicked row is " +
nameTextField.getText().toString());
if (nameTextField.isChecked()) {
// set check mark drawable and set checked property to false
value = "un-Checked";
nameTextField.setCheckMarkDrawable(R.color.colorAccent);
nameTextField.setChecked(false);
}
else {
// set check mark drawable and set checked property to true
value = "Checked";
nameTextField.setChecked(true);
}
Toast.makeText(context, value, Toast.LENGTH_SHORT).show();
}
});
return rowView;
}
In my MainActivity.java, I have used listView setOnItemClickListener
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
selected_Item = (String) arg0.getItemAtPosition(arg2);
Toast.makeText(AskForService.this, "Clicked item is" + selected_Item, Toast.LENGTH_LONG).show();
}
});
After implementing these code I can see -
ListView with checked TextView
ListView Can Scroll showing all the list items
on clicking a particular row..listview click listener is called and showing the Toast but checkbox becomes white(invisible) and sometimes another row get selected...Please help
Create a model class which contains a flag "isChecked" and set the data according to the model inside adapter
This link might be helpful : https://stackoverflow.com/a/40285759/8770539
Use an arraylist to store checked item's position.
call notifyDataSetChanged() for onclick()
Use this,
if(list.contains(position)) {
nameTextField.setChecked(true);
}
else {
nameTextField.setChecked(false);
}
nameTextField.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(list.contains(position))
{
list.remove(position);
}
else
{
list.add(position);
}
notifyDataSetChanged();
}
});
I want to update in and ArrayAdapter a TextView when user will click + or - button. I cannot figure out how can I change data of individual in ArrayApapter.
Here is a image for better explanation what I want to do :
public View getView(int position, View countView, ViewGroup parent) {
View listView = countView;
if (listView == null) {
listView = LayoutInflater.from(getContext()).inflate(R.layout.listview, parent, false);
}
word currentWord = getItem(position);
TextView foodName = (TextView) listView.findViewById(R.id.food);
Button minus = (Button) listView.findViewById(R.id.minus);
Button add = (Button) listView.findViewById(R.id.add);
TextView total = (TextView) listView.findViewById(R.id.total);
add.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
minus.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
return listView;
}
Whenever you are making a change through onclicklistener then just only change your data. like if your are using ArrayList> then just change the any value whatever you want like if your press 4th element with add+ then get the 4th item from the list and set it to +1. and then refresh your adapter with notifydatasetChanged().
In the above code you are only showing the UI part in the list whenever you will use data with you can do it then very easily.
Inside onClickListener, Increase or decrease the quantity and call onDataSetChanged().
I have a arraylist of buttons (reserveButtons) that I can display in a listview. I have made a search function which searches in my database and outputs a list of integers (resultID). They correspond to the indexes of reserveButtons I want to display.
Simply put, I want to do something like this when the search button is clicked:
ArrayAdapter<ReserveButton> adapter = new MyListAdapter();
ListView list = (ListView) myView.findViewById(R.id.resultslist);
list.setAdapter(adapter);
for (int result : resultID) {
adapter.add(reserveButtons.get(result));
}
So, for each result, I want to add the corresponding button to the listview.
Here is the private class MylistAadapter :
private class MyListAdapter extends ArrayAdapter<ReserveButton> {
public MyListAdapter() {
super(getActivity(), R.layout.list_item, reserveButtons);
}
#NonNull
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View itemView = convertView;
if(itemView == null) {
itemView = gettActivity().getLayoutInflater().inflate(R.layout.list_item, parent, false);
}
ReserveButton currentButton = reserveButtons.get(position);
//the resultItem is the id of the buttons
Button butt = (Button) itemView.findViewById(R.id.resultItem);
butt.setBackground(currentButton.getImage());
return itemView;
}
}
I know that getView will just display every reserveButton, but I want the code in getView to be executed when I add each button, but the position doesn't change since position = result in the for loop of the first code block.
//This code is inside MyListAdapter
#Override
public void add(ReserveButton object) {
/* What do I write here to inflate a list_item and give it
the background image reserveButton.get(result).getImage() */
super.add(object);
}
How do I override the add method of MyListAdapter so that I can add a reserveButton and change its background image for each result in the resultID list.
If the same thing can be accomplished without the add method, please do tell.
P.S: I do not want to just list every reserveButton and then filter them with the search; I want to display ONLY the buttons that the user is looking for.
I figured it out myself!
Basically, what I did was create a separate ArrayList of ReserveButtons and do the foreach loop like so:
int index = 0;
for (int result : resultID) {
//result is the single ID of an answer
answerButtons.add(index,reserveButtons.get(result));
index ++;
}
populateListView();
So I end up storing ONLY the buttons I want to display in the answerButtons list. And here is what happens in populateListView()
private void populateListView() {
ArrayAdapter<ReserveButton> adapter = new MyListAdapter();
ListView list = (ListView) myView.findViewById(R.id.resultslist);
list.setAdapter(adapter);
}
and the getView() method:
public View getView(int position, View convertView, ViewGroup parent) {
View itemView = convertView;
if(itemView == null) {
itemView = getActivity().getLayoutInflater().inflate(R.layout.list_item, parent, false);
}
//Just set the image of the corresponding answerButton
ReserveButton currentButton = answerButtons.get(position);
Button butt = (Button) itemView.findViewById(R.id.resultItem);
butt.setBackground(currentButton.getImage());
return itemView;
}
Problem solved. I haven't seen any answers to a problem like this, so this post should make it easily google-able for any newcomer who stumbles upon this problem.
I currently have a scrollview which I am adding rows to by inflating another xml layout. This is all working as it should and the row are all appearing correctly.
The issue I am having is that I am not sure how I can detect which button has been selected.
I have shown some example code for 1 on by buttons, simply put when this button is selected it toggles between 2 images. However, whenever I press the button it always automatially toggles the bottom rows button rather than the row in which the button has been selected.
Is there a way this can be implemented whilst still inflating a view to be used as a row (I do not want to dynamially create the rows, as this gets very messy)?
ScrollView scrollWeapons = (ScrollView)findViewById(R.id.scrollWeapons);
LinearLayout ll = new LinearLayout(this);
ll.setOrientation(LinearLayout.VERTICAL);
int i = 0;
for(final Weapon w : Game.Weapons)
{
View view = new View(this);
LayoutInflater inflater = (LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.menuweapons_row, null);
btnSelected = (ImageButton)view.findViewById(R.id.btnSelected);
btnSelected.setId(i);
btnSelected.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
EquipUnequip(w.WeaponID());
}
});
}
private void EquipUnequip(int WeaponId)
{
if(Game.Weapons.get(WeaponId).CharacterID() == ChrSelected)
{
btnSelected.setImageResource(R.drawable.eqip_but_idle);
}
else
{
btnSelected.setImageResource(R.drawable.eqip_but_press);
}
}
ll.addView(view);
i++;
The onClick method of OnClickListener has a parameter v. The value of v will be the View that was clicked, i.e. the ImageButton. All you have to do now is pass the View to EquipUnequip:
...
btnSelected.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
EquipUnequip(w.WeaponID(), (ImageButton)v);
}
});
...
private void EquipUnequip(int WeaponId, ImageButton btnSelected) {
if(Game.Weapons.get(WeaponId).CharacterID() == ChrSelected) {
btnSelected.setImageResource(R.drawable.eqip_but_idle);
} else {
btnSelected.setImageResource(R.drawable.eqip_but_press);
}
}
PS: This part seems a bit non-sensical to me:
View view = new View(this);
LayoutInflater inflater = (LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.menuweapons_row, null);
Why do you create a new View just to do nothing with it and replace it with the result from the LayoutInflater?
Edit
If you really need the row of the View (and it never changes) here are 2 alternatives:
Save row in the OnClickListener
class MyOnClickListener implements OnClickListener {
private final int rowIndex;
MyOnClickListener(int rowIndex) {
this.rowIndex = rowIndex;
}
#Override
public void onClick(View v) {
// do something with rowIndex
}
}
and use it instead of your anonymus class
or simply add a final variable outside your anonymus class:
// currentRowIndex calculated by your program
// i.e. incremented in every iteration
final int rowIndex = currentRowIndex;
btnSelected.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// do something with rowIndex
}
});
Add the info as tag to the button (currentRowIndex would be of type int):
btnSelected.setTag(currentRowIndex); // attach Integer data to the view
btnSelected.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
int rowIndex = (Integer)v.getTag();
// do something with rowIndex
}
});
Give the View parameter of onClick() to EquipUnequip(), cast this to ImageButton and use it. Otherwise you get the last created button.