I have a custom listview, each item have a imagebutton, i want to change image of each imagebutton immediately when I click. Each item in custom listview is a object named baiHat{}.
I use BaiHatAdapter like this, but it not chane immediately, i must scroll listview to see change.
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater=this.context.getLayoutInflater();
View row=inflater.inflate(this.resource, null);
TextView txtMs = (TextView) row.findViewById(R.id.ms);
TextView txtBh = (TextView) row.findViewById(R.id.bh);
TextView txtCs = (TextView) row.findViewById(R.id.cs);
TextView txtLr = (TextView) row.findViewById(R.id.lr);
ImageButton imglike = (ImageButton) row.findViewById(R.id.imageButton);
final BaiHat baiHat = this.objects.get(position);
txtMs.setText(baiHat.getTxtms());
txtBh.setText(baiHat.getTenBh());
txtCs.setText(baiHat.getTxtcs());
txtLr.setText(baiHat.getTxtLr());
imglike.setImageResource(baiHat.getImg());
imglike.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
xulythich(baiHat);
}
});
return row;
}
private void xulythich(BaiHat baiHat) {
if(baiHat.getThich()){
baiHat.setThich(false);
baiHat.setImg(R.drawable.addfav);
}else{
baiHat.setThich(true);
baiHat.setImg(R.drawable.added);
}
}
Create a selector file and assigning it as src would work. But as a better approach you can try to change it to togglebutton, since imageview is not meant to be clickable and give it the background of selector source.
It will just look like any imageview but with the capability of being clickable and changing its background from the selector file.
Related
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'm very new to Android dev and programming in general. My goal is to create a quiz in this format.
Each row is a custom view that includes a RadioGroup with 3 RadioButtons. And that is working fine, as you can see in the picture.
This is how the List is being populated:
private void populateListView() {
ArrayAdapter<QuizQuestion> adapter = new MyListAdapter();
ListView list = (ListView) findViewById(R.id.questionsListView);
list.setAdapter(adapter);
}
private class MyListAdapter extends ArrayAdapter<QuizQuestion> {
public MyListAdapter() {
super(ShortQuiz.this, R.layout.item_view, myQuestions);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View itemView = convertView;
if (itemView == null) {
itemView = getLayoutInflater().inflate(R.layout.item_view, parent, false);
}
QuizQuestion currentQuestion = myQuestions.get(position);
ImageView imageView = (ImageView) itemView.findViewById(R.id.item_icon);
imageView.setImageResource(currentQuestion.getImageId());
//Question
TextView question = (TextView) itemView.findViewById(R.id.item_question);
question.setText(currentQuestion.getQuestion());
//Game
TextView game = (TextView) itemView.findViewById(R.id.item_game);
game.setText(currentQuestion.getGameName());
//Option A
TextView optionA = (TextView) itemView.findViewById(R.id.item_radioA);
optionA.setText(currentQuestion.getOptionA());
//Option B
TextView optionB = (TextView) itemView.findViewById(R.id.item_radioB);
optionB.setText(currentQuestion.getOptionB());
//Option C
TextView optionC = (TextView) itemView.findViewById(R.id.item_radioC);
optionC.setText(currentQuestion.getOptionC());
return itemView;
}
}
The problem is that I do not know how to 'access' (set/get ids) each RadioGroup after creation in order to validate for right or wrong answers, which I want to do in one go pressing a button, as in: If the selected option is correct then +1 to Correct Answers.
Thanks.
Use a ViewHolder for each row. https://developer.android.com/reference/android/support/v7/widget/RecyclerView.ViewHolder.html
You can reference the items in each individual row. You can search for examples for how the ViewHolder is used in practice, but in general each row in the holder will be stored with a setTag() and retreived with a getTag(). So you can obtain the items in a view like:
view.getTag();
I have written a small app that has a ListView with a custom adapter. Each row contains some Buttons, which will change background color when clicked, and I got the list items to be clickable as well by putting
android:descendantFocusability="blocksDescendants"
in the xml of the list items. But now I have this weird bug where clicking on the list item reverts all clicked Buttons back to their original colorless state. How can I get the Buttons to keep their color?
Details:
Part of the custom adapter:
View.OnClickListener onButtonClicked = new View.OnClickListener() {
#Override
public void onClick(View button) {
View listItem = (View) button.getParent();
final long DBid = (long) listItem.getTag();//database ID
final Button b = (Button) button;
sqldataDataSource datasource = new sqldataDataSource(context);
datasource.open();
datasource.updateButton(DBid);
datasource.close();
b.setBackgroundColor(0xFF386F00);
}
};
As you can see, I change the background color AND change the database entry, so when the whole list is reloaded, the Button keeps its color (another part of my custom adapter):
public View getView(int i, View convertView, ViewGroup parent) {
LayoutInflater inflater =
(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.hrlistitems, parent, false);
Button b = (Button) rowView.findViewById(R.id.HRlistB);
b.setOnClickListener(onButtonClicked);
if(!(values.get(i).getB().equals(""))){
b.setBackgroundColor(0xFF386F00);
}
return rowView;
}
This works fine when going to another activity and coming back to this one. The buttons are created colored as expected.
So my guess was that the list is recreated from the original listItem array when an item is clicked, which is why I tried to fix this by reloading my database, like so (from my activity):
#Override
protected void onStart() {
super.onStart();
datasource = new sqldataDataSource(this);
datasource.open();
listItems = datasource.getOnlyRoutes(id);//this works fine
Collections.sort(listItems, HallenRoute.vergleichen());
if (mListView == null) {
mListView = (ListView) findViewById(R.id.listViewHalle);
}
adapter=new customAdapter(this, listItems);
setListAdapter(adapter);
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int pos, long nid) {
listItems.get(pos).increaseCount();
datasource.updateCountHR(listItems.get(pos));
listItems = datasource.getOnlyRoutes(id);//fix I tried, doesn't work
Collections.sort(listItems, HallenRoute.vergleichen());
adapter.notifyDataSetChanged();
}
});
}
But this doesn't work.
How can I get the ListView to either not reload on ItemClick or reload properly (i.e. from database)?
You don't have to reload the whole data for every Button click.
In your Button click you're just updating the data base and not your adapter dataset values, this is why you always get the old background color.
public View getView(int i, View convertView, ViewGroup parent) {
LayoutInflater inflater =
(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.hrlistitems, parent, false);
Button b = (Button) rowView.findViewById(R.id.HRlistB);
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View button) {
View listItem = (View) button.getParent();
final long DBid = (long) listItem.getTag();//database ID
final Button b = (Button) button;
sqldataDataSource datasource = new sqldataDataSource(context);
datasource.open();
datasource.updateButton(DBid);
datasource.close();
//b.setBackgroundColor(0xFF386F00); no need for this line, getView() method will take care of the background
//update your adapter dataset, eg: values.get(i).setB("newColor");
notifyDataSetChanged(); // to refresh your adapter
}
});
if(!(values.get(i).getB().equals(""))){
b.setBackgroundColor(0xFF386F00);
}
return rowView;
}
PS: It's better if you save your "database ID" in your Model object not as a View tag.
I'm trying to set an onClick listener on my ImageView in the Adapter of my GridView. However, weird thing happens: The content of the onClick function affects also some other Views in my GridView.
There is a good reason that I don't do the click listener on my GridView, so I need a solution for this via the ImageAdapter.
The logcat is called only once I click, but for some reason, other ImageViews are affected by this function.
Here's relevant code:
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if(convertView == null) {
holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.row_multiphoto_item, null);
holder.tickImageView = (ImageView) convertView.findViewById(R.id.tickImageView);
holder.imageView = (ImageView) convertView.findViewById(R.id.imageView1);
holder.imageViewLayout = (LinearLayout)convertView.findViewById(R.id.imageViewLayout);
convertView.setTag(holder);
}
else{
holder = (ViewHolder) convertView.getTag();
}
holder.imageView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
ImageView imageView = (ImageView)v;
int id = imageView.getId();
imageView.setVisibility(View.GONE);/*
if(!thumbnailsselection[id]){
Log.d(Global.TAG, "CLICK");
holder.tickImageView.setVisibility(View.VISIBLE);
holder.imageViewLayout.setBackgroundResource(R.drawable.imageview_selected);
thumbnailsselection[id] = true;
}
else{
holder.tickImageView.setVisibility(View.GONE);
holder.imageViewLayout.setBackgroundResource(R.drawable.imageview_unselected);
thumbnailsselection[id] = false;
}
*/
}
});
holder.imageView.setId(position);
holder.imageViewLayout.setId(position);
holder.tickImageView.setId(position);
holder.imageView.setImageBitmap(thumbnails[position]);
return convertView;
}
class ViewHolder {
ImageView imageView;
LinearLayout imageViewLayout;
ImageView tickImageView;
int id;
}
In baseAdapters, view are recycled. This means that if you set a view to invisible, you will add some other view invisible when you will scroll.
To avoid that, be sure to set again the visibility of yout view in the getView method:
holder.imageView.setVisibility(View.VISIBLE)
holder.imageView.setOnClickListener(new OnCl...
Also you will have to store each visibility state, in order to reassing to visible or invisible.
Im developing a small audio-streaming app. I have 5 items in a listview and Each listview has a seekbar with play-button. But whenever I click the playbutton of the first row in the listview, the seekbar progresses on the last row of the listview.
Please find my code below :
Adapter.java
public View getView(final int position, View convertView, ViewGroup parent) {
View vi = convertView;
if (convertView == null) {
vi = inflater.inflate(R.layout.songsinlistview, null);
}
seekbar = (SeekBar) vi.findViewById(R.id.seekBar); //seekbar is declared as public static
String streamURL = "http://xyz";
ImageButton button = (ImageButton) vi.findViewById(R.id.playbutton);
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(activity, PlayMusic.class);
intent.putExtra("URL", streamURL);
activity.startService(intent);
}
});
return vi;
}
PlayMusic.java is written as a service that does the streaming job.
How can i stream the song and show the seekbar progress in the same row of the listview which has been clicked.
*EDITED*
As the seekbar is public, Im able to access the same from the PlayMuisc.java.