Reset row in listview Android - android

In ListView, when i selected row it is set background color with reset previous selected one. but when listview scoll down it shows other row selected same backgound means one bye one page scroll down the row is selected.
Plz help me
In this two images i selected only first row but when i scroll the page 23 row is already selected. How to set selected row with scrollable page?
ListView lv = getListView();
lv.setTextFilterEnabled(true);
lv.setBackgroundResource(R.drawable.shape);
// on seleting single voter
// launching Edit Product Screen
lv.setOnItemClickListener(new OnItemClickListener() {
//mOnDoubleTapListener = listener;
#Override
public void onItemClick(AdapterView<?> parent, View view,int position, long id) {
boolean netFlag = new validationClass().haveNetworkConnection(context);
if(!netFlag) {
Toast.makeText(getApplicationContext(), "Data Connection is not available.", Toast.LENGTH_LONG).show();
return;
}
if (currentSelectedView != null && currentSelectedView != view) {
TextView textViewName = (TextView) currentSelectedView.findViewById(R.id.name);
TextView textViewPart = (TextView) currentSelectedView.findViewById(R.id.partno);
textViewName.setTextColor(getResources().getColor(android.R.color.darker_gray));
textViewPart.setTextColor(getResources().getColor(android.R.color.darker_gray));
} currentSelectedView =view
TextView textViewName = (TextView) view.findViewById(R.id.name);
TextView textViewPart = (TextView) view.findViewById(R.id.partno);
textViewName.setTextColor(getResources().getColor(R.color.text_color));
textViewPart.setTextColor(getResources().getColor(R.color.text_color));
}
}

There are two says to solve this:
A press/click on an item just sets the item as selected, and the user needs to click a button to act on the item.
Since your listview is fullscreen, have the onClick() record the position of the selected item. On a subsequent click, compare the current position to the last. If they aren't the same, just record the new position. If they are the same, go ahead with the operation. Or you could require the user to do a longclick (onItemLongClick()) to act on the selection if the current position is the same as the last.
Either way can help your app avoid detecting a click when the user is really trying to scroll. Android won't call the onClick() if the user starts scrolling right away. You can't control this.

Related

Changing background colour of listview item on click - and remembering it

I am populating a listview with strings from an ArrayList.
When a listview item is clicked i would like to change the background colour to green. <- Issue number one because I cannot change the item which is clicked.
After an item is clicked, I am adding its index to the list of items the user has selected, when the listview is first loaded I need it to set the background colour of all the listview items which have been selected to green too. <- Issue number 2 - I have been trying to do this with a for loop but do not know how to refer to a specific item in the listview to set the background colour!
Essentially, i think if someone can help me in how to change the colour of a selected listview item, i should be able to do the same thing but in a loop for all the userFoodPref which are saved?
animalsNameList = new ArrayList<String>();
userFoodPref = new ArrayList<Integer>();
getUserSelection();
getAnimalNames();
// Create The Adapter with passing ArrayList as 3rd parameter
ArrayAdapter<String> arrayAdapter =
new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, animalsNameList);
// Set The Adapter
animalList.setAdapter(arrayAdapter);
// register onClickListener to handle click events on each item
animalList.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
// argument position gives the index of item which is clicked
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
if(userFoodPref.contains(i)
){
userFoodPref.remove(i);}
else {
userFoodPref.add(i);
View item = animalList.getSelectedView();
item.setBackgroundColor(0x0000FF00);
}
String selectedAnimal=animalsNameList.get(i);
Toast.makeText(getApplicationContext(), "Animal Selected : "+selectedAnimal, Toast.LENGTH_LONG).show();
}
});
}
If I understand well, the problem is that when you set the backround of the item and then by example scroll the list and comeback to the previous position, it doens't remember that the backround is green for this specifix item.
I have faced this problem and to solve it easily :
Create a list a string for your name and a boolean (true = green, false = not green) and create an adapter for it and simply add
if (list.get(position).getBoolean) {
Currentitem.setBackgroundColor(0x0000FF00)}
And when you click on a item simply set the boolean of the item position to true and call notifydatasetchanged()

Custom listview click listener not working perfectly

I just needed help with a tricky situation in listview click listner. The thing is that I have populated a listview with custom adapters from remote servers. My listview contains 4 elements 2 images and 2 textview so the listview is loading perfectly from database but the issue is that I want listview to work only if the certain conditions match. Have a look at my code:
if (convertView == null) {
convertView = inflater.inflate(resource, null);
}
ImageView team1_photo,team2_photo;
TextView tournament;
team1_photo = (ImageView) convertView.findViewById(R.id.team1);
team2_photo = (ImageView) convertView.findViewById(R.id.team2);
tournament=(TextView) convertView.findViewById(R.id.tournament);
status=(TextView) convertView.findViewById(R.id.status);
ImageLoader.getInstance().displayImage(live_conveyerList.get(position).getTeam1_photo(), team1_photo);
ImageLoader.getInstance().displayImage(live_conveyerList.get(position).getTeam2_photo(), team2_photo);
tournament.setText(live_conveyerList.get(position).getTournament());
status.setText(live_conveyerList.get(position).getStatus());
liveListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
switch (position) {
case 0:
if(status.getText().equals("play on"))
{
Toast.makeText(getActivity(),"Result will be declared shortly",Toast.LENGTH_LONG).show();
}
else {
Intent fix1 = new Intent(getActivity(), Leaderboard.class);
startActivity(fix1);
}
break;
case 1:
if(status.getText().equals("play on"))
{
Toast.makeText(getActivity(), "Result will be declared shortly", Toast.LENGTH_LONG).show();
}
else{
Intent fix2 = new Intent(getActivity(), Leaderboard_1.class);
startActivity(fix2);
}
break;
default:
}
getActivity().overridePendingTransition(R.anim.activity_in, R.anim.activity_out);
}
}
);
return convertView;
}
}
So here, status is one of the textviews and it has two type of outputs. One is "play on" and other is "play off" so I want to open new activity only when it has populated play on in that peculiar row. Els,e there should be a toast only,
but it is not working for me. Any help would be nice, thanks.
my json is like this
{"list":[{"tournament":"Xavier college League","team1_photo":"http:\/\/thehostels.in\/judgement_files\/images\/India.png","team2_photo":"http:\/\/thehostels.in\/judgement_files\/images\/Australia.png","status":"play on"},{"tournament":"ITM college League","team1_photo":"http:\/\/thehostels.in\/judgement_files\/images\/India.png","team2_photo":"http:\/\/thehostels.in\/judgement_files\/images\/Australia.png","status":"play off"}]}
In your case 0 you have "Play on" with a capital P, but equals takes the case into account by default, could it be your issue?
Edit : Ok I think I got it
You define the onItemClickListener not once but for each and every item, so that at the end of list population, your listener is based on the status of the last item of your list
You should define onItemClickListener only once, and you will have clicked item with view and position arguments
For instance you may want to store the list of all your items as a field, and in your onItemClickListener you will get clicked item from the position, and thus get its status
With the view parameter, you should be able to access the fields' values through findViewById
Edit 2:
What I meant is the following : there is only one onItemClickListener that needs to be defined and onItemClick method will provide the position and the view of clicked item.
That means that each time user will click any item of the list, the listener will be called, but there is not one different listener for each different row.
With that in mind, in the onItemClick, with the view and/or the position, you can access the status textview, get its value and then do all the stuff you need to do with your toast and intent. I hope it's clearer than before
Edit 3:
That should do your thing : in your listener, before your switch,
TextView currentStatus=(TextView) convertView.findViewById(R.id.status);
And then you replace all the references to status inside your listener by currentStatus. And you will need to define the listener only once outside of your getView method, even outside your adapter, rather where your listView is defined and your adapter is added to it

Android: How to color the 2 TextView in the selected row of a ListView

I'm trying to make a Music Player in Android, and yesterday I got the idea to set the currently playing song colored in the ListView.
At the beginning I set that every time I start a song, a new BaseAdapter inflate a layout with 2 TextView (title and artist) and if the song is the same in the MediaPlayer, the 2 TextView become blue.
It was working fine, but i noticed that when I pick a song, the ListView scrolls immediately up because the Adapter is recreated.
Searching the web I found that I could create a new method in the BaseAdapter class, where if I pass the ListView and the song position I could color it, so I would call the setAdapter(songList) only in the onCreate method.
Yeah, but it doesn't work.
-SongAdapter:
public void updateData(ListView listView, int position){
if (MainActivity.isMusicStarted) {
//These 2 lines of code return a NullPointerException
songView = (TextView) listView.getSelectedView().findViewById(R.id.song_title);
artistView = (TextView) listView.getSelectedView().findViewById(R.id.song_artist);
//The following 2 lines, if de-commented, color only the two TextView in the first shown row instead of the selected row
//songView = (TextView) listView.findViewById(R.id.song_title);
//artistView = (TextView) listView.findViewById(R.id.song_artist);
if (position==MusicService.getCurrentSong()) {
songView.setTextColor(ContextCompat.getColor(context, R.color.colorPrimary));
artistView.setTextColor(ContextCompat.getColor(context, R.color.colorPrimary));
}
else{
songView.setTextColor(ContextCompat.getColor(context, android.R.color.primary_text_light));
artistView.setTextColor(ContextCompat.getColor(context, android.R.color.secondary_text_light));
}
}
}
-MainActivity: (called at the end of a OnCompletitionListener())
public static void colorSongSelected(int position){
songAdapter.updateData(songView, position);
}
listview.getSelectedView() return the view corresponding to the currently selected item, or null if nothing is selected.
For more information how to select a item in listview you can see this answer

listview getting new instance when swiping the listview

I have one listview in my application,it contains two rows one for task and another one for alarm,date,severity. Initially first row of the list item only displayed for all list item and the second one is invisible. When i click the list item the second row displayed for that item as well as click another list item at that time the above list item closed that second row. Its working fine for me...My problem is if i open one list item and then swipe the listview at then i click the another list item at that time the above one cannot be closed because the above list item instance will be chnaged.please any one help me how to solve this problem...
int lastselectedPosition == -1
#Override
public void onItemClick(AdapterView<?> arg0, View view, int position,
long id) {
TextView textviewDate=(TextView)view.findViewById(R.id.taskTimeidDaytoDay);
selectedtaskDate=textviewDate.getText().toString().trim();
if (lastselectedPosition == -1) {
Log.i(TAG,"Loopif:"+lastselectedPosition);
TextView twTaskTime = (TextView) view
.findViewById(R.id.taskTimeidDaytoDay);
TextView twSeverity = (TextView) view
.findViewById(R.id.severityidDaytoDay);
TextView twAlarm = (TextView) view
.findViewById(R.id.alarmidDaytoDay);
twAlarm.setVisibility(view.VISIBLE);
twSeverity.setVisibility(view.VISIBLE);
twTaskTime.setVisibility(view.VISIBLE);
lastselectedPosition = position;
lastSelectedItem = arg0.getChildAt(position);
} else {
// Log.i(TAG,"LoopElse:"+lastselectedPosition);
lastSelectedItem.findViewById(R.id.taskTimeidDaytoDay)
.setVisibility(lastSelectedItem.GONE);
lastSelectedItem.findViewById(R.id.severityidDaytoDay)
.setVisibility(lastSelectedItem.GONE);
lastSelectedItem.findViewById(R.id.alarmidDaytoDay).setVisibility(
lastSelectedItem.GONE);
if (lastselectedPosition != position) {
view.findViewById(R.id.taskTimeidDaytoDay).setVisibility(
view.VISIBLE);
view.findViewById(R.id.severityidDaytoDay).setVisibility(
view.VISIBLE);
view.findViewById(R.id.alarmidDaytoDay).setVisibility(
view.VISIBLE);
lastselectedPosition = position;
lastSelectedItem = arg0.getChildAt(position);
} else {
lastselectedPosition = -1;
lastSelectedItem = null;
}
}
GetView():
#Override
public View getView(int position, View view, ViewGroup parent) {
Log.i("XXXX", "Inside getView");
final DaytoDayTaskGetterSetter objDaytoDaygetset=getItem(position);
TextView textviewTask;
TextView txtviewAlarm ,txtviewTaskTime ,txtviewSeverity;
Log.i(TAG,"InsideGetView:"+position);
LayoutInflater inflater=(LayoutInflater)context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
if(view==null)
{
view=inflater.inflate(R.layout.daytodaylistlayout,null);
}
Log.i("XXXX", "before first test");
textviewTask=(TextView)view.findViewById(R.id.tasknameidDaytoDay);
txtviewAlarm=(TextView)view.findViewById(R.id.alarmidDaytoDay);
txtviewSeverity=(TextView)view.findViewById(R.id.severityidDaytoDay);
txtviewTaskTime=(TextView)view.findViewById(R.id.taskTimeidDaytoDay);
return view;
}
In first i click the "gdfgdtet" list item it show another row and then i click the second list item "dfgsdgsd" at that time the above list item "gdfgdtet" closed the second row.This is a normal output.Suppose if i open the "gdfgdtet" list item and then swipe the listview at that time both of "gdfgdtet" "dfgsdgsd" will be opened and crashed...because the above one list item reference changed when i am swiping please how to solve this problem...
I'll try to provide you a good answer that explains why you are having this problems, but the general idea is that you have to see this video - http://www.youtube.com/watch?v=wDBM6wVEO70
please take my words kindly - you don't seems to understand what ListView + BaseAdapter recycling mechanism is all about, and I strongly recommend you see the full video I linked you to, and read more about that.
in general, the specific problem in your code is that you are holding reference to listview item (lastSelectedItem), then trying to use it latter assuming it's still representing same list item. that's wrong. in that stage (after scrolling) the view already been recycled to represent another item in the list (based on the adapter implementation).
listView's number of childs is not the size of adapter.getCount()!!!!!!!!
listViews's number of childs = number of visible list items on screen + 1 + headers + footers
let's say you have the 5 first items visible on screen, then you are scrolling down. when you see the 7 item you actually see the same view instance that used to show the first list item and been recycled.
getView will call in this stage with convertView != null and position in the adapter to let you reuse the item by putting new values such different text/image to the same instance
this mechanism provides ability to display list of "infinite" number of items in the list, and holding in memory only a few number of views. imagine that you have list of 5000 items in the list, and each one of them have different view instance - you would get outOfMemory exception in a sec!
complete explanation about that would be hard to write in stackoverflow answer's context.
it just too long trying to explain one of the most important and complex UI components in android, but this links would be a good start:
http://www.youtube.com/watch?v=wDBM6wVEO70
How ListView's recycling mechanism works
http://mobile.cs.fsu.edu/the-nuance-of-android-listview-recycling-for-n00bs/
if you are interstead in "quick" fix for your specific problem, the solution would be:
hold in the data structure represents your list item additional field indicating if it in "close" or "open state. when item been clicked - change the data accordinly and call notifyDatasetChanged(). inside the getView() check if item is open or close and populate it accordinly
by the way - it's not only "quick fix" solution, but also the right thing to do anyway
You should pay attention to Tal Kanel's answer and consider this one to be an extension to it. His advice will help you in the long run.
Add a boolean field to DaytoDayTaskGetterSetter class:
public class DaytoDayTaskGetterSetter {
....
....
boolean open;
public DaytoDayTaskGetterSetter (.., .., boolean o) {
....
....
open = o;
}
....
....
public boolean shouldOpen() {
return open;
}
public void setOpen(boolean o) {
open = o;
}
}
In your getView(), check if the object has its open value set:
DaytoDayTaskGetterSetter obj = (DaytoDayTaskGetterSetter) getItem(position);
if (obj.shouldOpen()) {
// Set visibility to true for the items
} else {
// Set visibility to false for the items
}
On list item click, traverse the list and set open for all list items to false. Use the position to retrieve DaytoDayTaskGetterSetter and set its open to true:
#Override
public void onItemClick(AdapterView<?> arg0, View view, int position, long id) {
for (DaytoDayTaskGetterSetter obj : listContainingObjects) {
obj.setOpen(false);
}
DaytoDayTaskGetterSetter clickedItem = (DaytoDayTaskGetterSetter)
yourAdapter.getItem(position);
clickedItem.setOpen(true);
yourAdapter.notifyDataSetChanged();
}
Edit 1:
#Override
public void onItemClick(AdapterView<?> arg0, View view, int position, long id) {
DaytoDayTaskGetterSetter clickedItem = (DaytoDayTaskGetterSetter)
yourAdapter.getItem(position);
if (clickedItem.shouldOpen()) {
clickedItem.setOpen(false);
} else {
for (DaytoDayTaskGetterSetter obj : listContainingObjects) {
obj.setOpen(false);
}
clickedItem.setOpen(true);
}
yourAdapter.notifyDataSetChanged();
}

Passing Which ListView Item was Clicked to the Next Screen - Android

I have a ListView in Screen 1 where I have a few items . The User Clicks on an item in the Listview and Screen2 pops up . But What appears in Screen2 depends on what item was clicked in Screen 1
For Ex - User Clicks A in Screen 1 - Words starting from A come up in Screen 2
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// When clicked, Open the Next Screen
Intent r=new Intent(Dummy.this ,CricksList.class );
r.putExtra("extra", id);
startActivityForResult(r, position);
}
I have passed the item which was clicked on . But I want to Display on Screen 2 what the user clicked on - as an item in the List View . How do I do that ??
Create another activity and put code like this in it.....
TextView textview = (TextView) findViewById(R.id.myEditText);
String Name = getIntent().getStringExtra("extra");
textview.setText(Name);
Use the extra field from the receiving intent, and based on that, lookup the record in your data source(database, contentprovider, array) and inflate a view that suit your needs.
Try to create the other activity which displays the clicked item. Then, call the second activity on click.

Categories

Resources