Highlighted item changes position when scrolling listview. If i choose first item in listview and scrolling to the end, between every 7-8 item is selected. And even highlighted item lose its position and highlighting 3rd item. i dont use custom adapter for listview, only for textview. Here is code:
lv=(ListView) findViewById(R.id.listView);
myadaptersong = new ArrayAdapter<String>(this, R.layout.custom_item, R.id.menu, music);
lv.setAdapter(myadaptersong);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if(menuItem != null) menuItem.setBackgroundColor(Color.parseColor("#ffffff"));
menuItem = view;
menuItem.setBackgroundColor(Color.parseColor("#a2aed3"));
});
}
UPDATE:
Custom Adapter is this
public class CustomAdapter extends BaseAdapter {
String music[];
int flag[];
LayoutInflater inflater;
public CustomAdapter(Context context, String[]music, int []flag)
{
this.music=music;
this.flag=flag;
inflater=(LayoutInflater.from(context));
}
#Override
public int getCount() {
return music.length;
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View view, ViewGroup viewGroup) {
view=inflater.inflate(R.layout.custom_item,viewGroup,false);
TextView name= (TextView)view.findViewById(R.id.menu);
name.setText(music[position]);
return view;
}
}
what should i do here?
The code you posted won't work the way you intend (as you already noticed). Let's say your ListView shows 4 items on screen and you clicked on the first item (item 0, highlighting it by changing its background color). When you scroll down to see more views and item 0 goes off the screen, the view from item 0 will be recycled to show a later item (say, item 6).
Now item 6 is using the view whose background color you already changed, so it will be highlighted. As the view continues to go off-screen and be re-used, other random rows in the ListView will be highlighted.
You will need to implement a custom adapter to do what you are trying to do.
Related
I have a problem with my listview. What I want to do is when I click an item in the listview, it should remain highlighted, and when I click another item, new item should be highlighted.
Here's what I've done so far:
public void setSelection(int position) {
if (selectedPos == position) {
selectedPos = NOT_SELECTED;
} else {
selectedPos = position;
}
notifyDataSetChanged();
}
Adapter GetView:
if (position == selectedPos) {
// your color for selected item
viewHolder.tvTitle.setTextColor(context.getResources().getColor(R.color.main_blue));
viewHolder.tvDetails.setTextColor(context.getResources().getColor(R.color.main_blue));
}
else {
// your color for non-selected item
viewHolder.tvTitle.setTextColor(context.getResources().getColor(R.color.dark_grey));
viewHolder.tvDetails.setTextColor(context.getResources().getColor(R.color.dark_grey));
}
Activity:
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
episodesAdapter.setSelected(position);
}
});
This is working as expected, but the problem is with notifyDataSetChanged, it's delaying the time to highlight item that is being selected next. What should I do to automatically get it highlighted? Any help would be truly appreciated. Thanks!
Update:
I tested and it took 8-10secs before a new item is highlighted. There is a slight delay in highlighting an item.
I am using below code to setcolor of a selected item of a listview. The rule is only one should be colored. But with below code if I select 2 views both get colored. Can you please help me get all other views in the listview so that when I click on certain view all other views i set to different color and the selected view i set a different color(Green in this case).
Please let me know if any other solution?
lv = (ListView) view.findViewById(R.id.listf);
lv.setAdapter(text![enter image description here][1]Adapter);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
TextView v = (TextView) view.findViewById(R.id.template_text);
view.setBackgroundColor(Color.GREEN);
}
});
I resolved the problem using the below:
I put a loop where only the selected list item is set in RED whereas all others were set in Green, in this way only only one list item will be colored on selected.
lv = (ListView) view.findViewById(R.id.listf);
lv.setAdapter(Adapter);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
for (int i = 0; i < 3; i++)
{
if (position == i)
{
parent.getChildAt(i).setBackgroundColor(Color.RED);
}
else
{
parent.getChildAt(i).setBackgroundColor(getResources().getColor(R.color.Dark_Green);
}
}
TextView v = (TextView) view.findViewById(R.id.template_text);
view.setBackgroundColor(Color.GREEN);
}
});
As you told you are not able to change adapter code, you can prefer solution 2.
Solution 1: Create one variable int selectedPosition and method setSelected in your adapter class
int selectedPosition = -1;
public void setSelected(int position)
{
selectedPosition = position;
notifyDatasetChanged();
}
Edit getView() of the adapter class and include following code
if(selectedPosition==position)
{
templateTextView.setBackgroundColor(Color.GREEN);
}
else templateTextView.setBackgroundColor(Color.BLUE);// default textView color
Solution 2: keep reference of previously selected textView as well each time change the color of currently selected textview to green andd previous one to blue
TextView previousSelected = null;
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if(previousSelected!=null)
previousSelected.setBackgroundColor(Color.BLUE);
TextView v = (TextView) view.findViewById(R.id.template_text);
view.setBackgroundColor(Color.GREEN);
previousSelected = v;
}
});
How to assign a color to the selected item of ListView? I read
Creating a Navigation Drawer and downloaded the sample. They use android:background="?android:attr/activatedBackgroundIndicator". When I select an item, its color keeps being blue. When I select a previously selected item, its color slightly changes.
The min. API I need is 10.
You can do it with two ways:
1) Using checkBox by creating an item for the ListView and pass it through the adapter and the checkBox will handle the check and uncheck operations automatically.
2) Using the adapter by creating an integer value to hold the position of the selected item and check for it in the method getView() to draw it with different color
adapter.class:
private static int selectedItemPosition = -1;
public static void setSelectedITem(int i){
selectedItemPosition = i;
}
public static void getSelectedITem(){
return i;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if(position == selectedItemPosition){
//Highlight your item or ViewHolder
textView.setBackgroungColor(R.color.gray);
//Complete the actions
return view;
}
and from your activity or fragment set the position as following
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,int position, long id) {
adapter.setSelectedITem(position);
adapter.notifyDataSetChanged();
}
});
I hope it helps
I have a layout for list item, which consists of two LinearLayouts. What I want to achieve is: when item is clicked, second LinearLayout should become visible/gone, depending on the current visibility.
I am experimenting with this code:
getListView().setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
view.getViewById(R.id.id_of_the_second_linear_layout).setVisibility(View.GONE);
}
});
However when item is clicked, several other linear layouts (in different items) become visible/hidden. Why?
Update:
Adapter:
public class ExpensesCursorAdapter extends SimpleCursorAdapter implements SimpleCursorAdapter.ViewBinder {
public ExpensesCursorAdapter(Context context, Cursor cursor) {
super(context, R.layout.single_expense, cursor,
new String[]{
ExpenseContract._AMOUNT,
CategoryContract._NAME,
ExpenseContract._DATE
},
new int[]{
R.id.expense_amount,
R.id.expense_category,
R.id.expense_date
},
CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
setViewBinder(this);
}
public View getView(int position, View convertView, ViewGroup viewGroup) {
View v = super.getView(position, convertView, viewGroup);
final View expandablePanel = v.findViewById(R.id.expandable_panel);
expandablePanel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
expandablePanel.setVisibility(view.getVisibility() == View.GONE ? View.VISIBLE : View.GONE);
}
});
return v;
}
#Override
public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
if (columnIndex == cursor.getColumnIndex(ExpenseContract._AMOUNT)) {
return handleAmountView((TextView) view, cursor);
}
else ...
return false;
}
private boolean handleAmountView(TextView view, Cursor cursor) {
TextView textView = (TextView) view;
Double amount = ExpenseDbHelper.getAmount(cursor);
String formattedAmount = new DecimalFormat("##.00").format(amount);
textView.setText(formattedAmount);
return true;
}
}
Each item has LinearLayout already added in XML, I want to toggle visibility flag, if possible.
You are writing your logic on wrong places. You want to listen clicks of views inside listitem. Write your logic in Adapter's getView method. In your getView logic can be like this
ll1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
ll2.setVisibility(View.GONE);
}
});
ll2.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
ll1.setVisibility(View.GONE);
}
});
Something like this.
When you scroll through the list items, some layouts will hide and un-hide, in that case, if you are targeting just one view to be visible at a time (that is just considering one cell at a time), then you could maintain the position of the item clicked, or the id, since you are using a cursorAdapter. Else if you are considering more than one cell then maintain a list where in you store each id of the cell that has been tapped on.
Pass the list or the single position value to the adpater, and in the getview compare the id or position and then perform the visiblity code.
Hope this hint helps.
I want to add gradient for each row. What I've tried to do is on listview label put this attribut, android:background="#drawable/mygradient". But All I get is this gradient displayed all along the list. What I want is this gradient to be displayed for each item.
Thanks in advance
You can provide a custom adapter for your list view and set the gradient as the background in its getView method. Something like this:
public class MyAdapter extends BaseAdapter {
List<MyDataType> myData;
Context context;
public MyAdaptor(Context ctx, List<MyDataType> myData) {
this.myData = myData;
this.context = ctx;
}
public int getCount() { return myData.size() };
public Object getItem(int pos) { return myData.get(pos); }
public long getItemId(int pos) { return 0L; }
public View getView(int pos, View convertView, ViewGroup parent) {
//this is where you can customise the display of an individual
//list item by setting its background, etc, etc.
...
//and return the view for the list item at the end
return <List item view>;
}
}
Then you can set this adapter as the adapter for your list:
ListView myList = <initialise it here>
myList.setAdapter(new MyAdapter(getContext(), listData);
Now whenever a list item needs to be displayed, getView method will be called, where you'll perform all the necessary display customisation, including setting the background.
Instead of setting background property set Selector of list, as below:
android:listSelector="#drawable/list_selector_background"