I am using a list fragment to in a customized navigation drawer. I want to change the color of a text view in the list item while pressing. I am passing item click position to adapter and notify the adapter. But it is not working. but when i set the adapter again it is working. But the movement is not smooth . What should i do to overcome this issue?
Following is the ListItem click of fragment,
#Override
public void onListItemClick(ListView lView, View v, final int position, long id) {
super.onListItemClick(lView, v, position, id);
adapter.setSelectedIndex(position);
adapter.notifyDataSetChanged();
lView.setAdapter(adapter);
}
and the adapter having the following code,
public void setSelectedIndex(int ind)
{
selectedIndex = ind;
notifyDataSetChanged();
}
my onactivity created
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
menuitemlist=new ArrayList<MenuItem>();
menuitemlist.clear();
for(int i=0;i<menulist.length;i++){
MenuItem item=new MenuItem();
item.icon=iconlist[i];
item.menuText=menulist[i];
item.status=0;
menuitemlist.add(item);
}
adapter=SlidingListAdapter.newInstance(myActivity, menuitemlist);
setListAdapter(adapter);
}
Method 1
Set your list adapter outside `onListItemClick()`
lView.setAdapter(adapter);
#Override
public void onListItemClick(ListView lView, View v, final int position, long id) {
super.onListItemClick(lView, v, position, id);
adapter.setSelectedIndex(position);
adapter.notifyDataSetChanged();
}
Method 2
View lastSelectedView = null;
#Override
public void onListItemClick(ListView lView, View v, final int position, long id) {
super.onListItemClick(lView, v, position, id);
if(lastSelectedView != null){
TextView txtView = (TextView)lastSelectedView.findViewById(R.id.x);
txtView.setTextColor(defaultColor);
}
TextView txtView = (TextView) v.findViewById(R.id.x);
txtView.setTextColor(pressedColor);
lastSelectedView = v;
}
Method 3
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:color="#ff0000"/>
<item android:state_selected="true" android:color="#00ff00"/>
<item android:color="#000000"/>
</selector>
and set this selector file as textColor for TextView
Related
I don't want to call onItemClick when onItemLongClick is called.
I am using SlideAndDragListView and returning true only in onItemLongClick.
matchedUsersListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
InviteMatchedUsersFragment.this.onItemLongClick(parent,view,position,id);
return true;
}
});
#Override
public void onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
ImageView view1 = (ImageView) view.findViewById(position);
matchedPassengersAdapter.onUserClick(view1, position);
}
In OnItemClick I am doing it differently
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Log.d(LOG_TAG, "onMatchedUserSelection()");
if(matchedPassengersAdapter.getSelectedPassengersCount() != 0)
{
ImageView view1 = (ImageView) view.findViewById(position);
matchedPassengersAdapter.onUserClick(view1, position);
}
else {
//onItemClickGoesHere
}
}
#Override
public void onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
ImageView view1 = (ImageView) view.findViewById(position);
matchedPassengersAdapter.onUserClick(view1, position);
}
This May helps You
Ref: Set long click listener for listview
Your question is very similar to this one, but it looks like it's not an exact duplicate.
What you've noticed is that the ListActivity class does not have a method override specifically for this case.
In order to add this functionality as a method override, your class should implement the AdapterView.OnItemLongClickListener interface, and then you can add the onItemLongClick() method override, which acts just as the onListItemClick() method override you already have, but responds to long clicks.
Just make sure that you follow instructions from this answer, you must use android:longClickable="true" in the layout xml, or call listview.setLongClickable(true);
Ex
public class MainActivity extends ListActivity implements AdapterView.OnItemLongClickListener {
ListView listview;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView listview = (ListView) findViewById(R.id.list);
listview.setLongClickable(true);
}
#Override
public boolean onItemLongClick(AdapterView<?> l, View v,
final int position, long id) {
Toast.makeText(this, "long clicked pos: " + position, Toast.LENGTH_LONG).show();
return true;
}
protected void onListItemClick(ListView l, View v, final int position, long id) {
super.onListItemClick(l, v, position, id);
Toast.makeText(this, "short clicked pos: " + position, Toast.LENGTH_LONG).show();
}
//....................
The code populates the listview with items using baseadapter. On clicking on the item it changes background color and goes to the next activity. Now i want to change the back ground color on first click and it should stay selected. Then on next click it should go to the next activity. Is it possible to do so.
Activity
nameList = (ListView) findViewById(R.id.list_names);
nameList.setAdapter(listAdapter);
listAdapter.notifyDataSetChanged();
nameList.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long viewId)
{
TextView PCNtv = (TextView) view.findViewById(R.id.value_Name);
String P_Name = PCNtv.getText().toString();
Intent intents = new Intent(getApplicationContext(), Activity2.class);
intents.putExtra("P_Name", P_Name);
view.setSelected(true);
startActivity(intents);
}
});
In drawable
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:drawable="#drawable/blue_color"/>
<item android:state_pressed="true" android:drawable="#drawable/white_color"/>
<item android:state_focused="true" android:drawable="#drawable/red_color"/>
</selector>
Use the views selected property to detect the second click. First click will select the view, the second will open the activity.
nameList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long viewId)
{
TextView PCNtv = (TextView) view.findViewById(R.id.value_Name);
String P_Name = PCNtv.getText().toString();
if ( view.isSelected() ) {
Intent intents = new Intent(getApplicationContext(), Activity2.class);
intents.putExtra("P_Name", P_Name);
startActivity(intents);
}
view.setSelected(true);
});
}
Update
The selection is lost when the users presses the view again, so the code above does not work. Here is a solution involving the adapter tracking the currently selected position.
The click event:
nameList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
// Check to see which item in the adapter is already
// selected, if the same has been selected twice, start new activity
if ( i == ((TestAdapter)adapter).getSelectedIndex()) {
// Start your new activity here.
Log.d("TAG", "second push");
}
((TestAdapter)adapter).setSelectedIndex(i);
}
});
You did not show the code for your adapter, so here is a simple one with the selected index added:
public class TestAdapter extends ArrayAdapter<String> {
private final Activity context;
private int mSelection = -1;
public TestAdapter(Activity context, String[] objects) {
super(context, R.layout.text_layout, objects);
this.context = context;
}
// Call this when an item is clicked, this sets the
// internal index for the selected item and notifies the view
// that the data has changes, this will force the view to draw
// allowing it to correctly highlight the selected item
public void setSelectedIndex(int index) {
mSelection = index;
notifyDataSetChanged();
}
// This is needed for the click listener to check to see which
// item is already selected
public int getSelectedIndex() {
return mSelection;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = context.getLayoutInflater();
View rowView = inflater.inflate(R.layout.text_layout, null);
TextView tv = (TextView)rowView.findViewById(R.id.text3);
tv.setText(getItem(position));
// Adds or removes the selection on the view so
// it will display as selected
if ( mSelection == position ) {
tv.setSelected(true);
} else {
tv.setSelected(false);
}
return rowView;
}
}
Updated: added inline comments
I have a spinner (only relevant parts of code)...
protected void onCreate(Bundle savedInstanceState) {
Spinner to_spinner = (Spinner) findViewById(R.id.to_spinner);
List<Unit> list = myDbHelper.getAllUnits();
SpinnerUnitAdapter tUnitAdapter tUnitAdapter = new SpinnerUnitAdapter(this, android.R.layout.simple_spinner_item, list);
to_spinner.setAdapter(tUnitAdapter);
to_spinner.setOnItemSelectedListener(onItemSelectedListenerTo);
}
with an onItemSelectedListener
AdapterView.OnItemSelectedListener onItemSelectedListenerTo = new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> adapterView, View view,
int position, long id) {
// do stuff
}
#Override
public void onNothingSelected(AdapterView<?> adapter) {
}
};
When an item is selected (i.e. where it says: "do stuff"), I would like to set/change the text of the selected spinner item. (Note that this is not the same as setting the spinner position (with setSelection()).
I was thinking of doing this with
tUnitAdapter.getView(position, ?, ?).setText("new text");
Am I on the right track? What to put as second ("convertView") and third ("parent") argument in getView. My spinner adapter looks like:
public class SpinnerUnitAdapter extends ArrayAdapter<Unit> {
...
#Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView label = new TextView(mContext);
label.setTextColor(Color.BLACK);
label.setTextSize(mContext.getResources().getDimension(R.dimen.list_row_font_size));
label.setGravity(Gravity.CENTER);
label.setText(getItem(position).getName());
return label;
}
}
Am I on the right track?
No. You should do the following steps: (in the onItemSelected method)
Update your model (the array of items you passed to the adapter) so that the item at position index takes the new name.
Issue notifyDataSetChanged on the adapter object. Alternatively, you can do this manually by ((TextView) view).setText(new_name);
Note: In onItemSelected method, adapterView points to your spinner view and view points to the row view just selected.
UPDATE #1
public void onItemSelected(AdapterView<?> adapterView, View view, int position, long id) {
((TextView) view).setText("new name");
}
UPDATE #2
For this, you should use Java interface to implement a callback which is called once the dialog is closed.
public void onItemSelected(AdapterView<?> adapterView, final View view, int position, long id) {
Dialog dialog = new MyDialog(context, new MyDialog.OnItemSelectListener(){
#Override
public void onItemSelected(String newName){
((TextView) view).setText(newName);
}
});
dialog.show();
}
And declare interface OnItemSelectListener in your MyDialog class.
You can change the text of spinner when you click each item so you should implement onClickListener
public class SpinnerUnitAdapter extends ArrayAdapter<Unit> {
...
#Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView label = new TextView(mContext);
...
label.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// change label text here
// label.setText(...);
}
});
return label;
}
}
Hope this help
I think I found the solution. I can just do:
public void onItemSelected(AdapterView<?> adapterView, View view,
int position, long id) {
TextView tv = (TextView) adapterView.getSelectedView();
tv.setText("new text");
}
By default i need to show one item as highlighted in horizontal list view and when the user selected another item in the horizontal list view i want to highlight that item(removing the earlier and highlight the currently selected) for that i'm trying with the following code,in my adapter
Adapter:-
int selectedIndex;
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
v = LayoutInflater.from(parent.getContext()).inflate(
R.layout.hlist_rowitem, null);
if (position == selectedIndex) {
v.setBackgroundColor(Color.parseColor("#abcdef"));
}
}
and after selecting another item from activity in from the list view what to do in activity to change highlighting position of the item.
Activity:-
int sIndex;
sIndex = getIntent().getIntExtra("POSITION", 0);
hlAdapter = new HSelectedAdapter(InsuranceCard.this, rowItems, sIndex);
hListView.setAdapter(hlAdapter);
hListView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,int position, long id) {
//other code goes here
}
});
I'd would use a color state list resource and have the ListView handle the selection with setSelection(position).
The color list would look something like this:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:color="#aabbcc"/> <!-- pressed -->
<item android:state_activated="true"
android:color="#fedcba"/> <!-- selected -->
<item android:color="#abcdef"/> <!-- default -->
</selector>
and it should be set as background of the R.layout.hlist_rowitem or as listSelector on the listview.
Edit:
To change the selection when receiving a click event:
hListView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,int position, long id) {
hListView.setSelection(position);
}
});
The ListView will deselect the old/default item and selects the new item at the specified position.
Edit 2: By default the ListView don't have a choice mode set so make sure you either set it in xml or in code: listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
you can achieve this in two ways.
manually clear all item and set selected in onItemClick()
listview.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
for (int i = 0; i < adapter.getCount(); i++) {
View item = listview.getChildAt(i);
if (item != null) {
item.setBackgroundResource(R.drawable.unselected);
}
arg1.setBackgroundResource(R.drawable.selected);
}
}
});
use selector and let listview do itself.
/drawable/selector_list.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/selected" android:state_selected="true"/>
<item android:drawable="#drawable/selected" android:state_activated="true"/>
<item android:drawable="#drawable/unselected"/>
</selector>
and add android:listSelector="#drawable/selector_list" to your listview
add listitemclick.xml
in your drawblw folder this is the code.
2)then in your hlist_rowitem.xml set background="#drawable/listitemclick"
follow these steps:
1)declare one boolean array.
public static boolean ClickItem[];
2)inside oncreate
ClickItem=new boolean[your array size];
Arrays.fill(ClickItem, false);
in your adapter write this code
a)
if ClickItem[pos]
{
v.setBackgroundColor(Color.parseColor("#abcdef"));
}else
a)
v.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Arrays.fill(ClickItem, false);
ClickItem[pos]=true;
adapter1.notifyDataSetChanged();
}
});
I know it sounds very simple, and there are questions about this. But none of it could solve my problem. So here we go:
I want to change background color of a list item in a ListActivity when user clicks on it, and change it back to original color when user clicks again (i.e. Select/Unselect item sort of look)
I tried using getChildAt, it works perfectly if I have all the items visible in one screen without having to scroll.
Code:
getListView().getChildAt(position).setBackgroundColor(Color.CYAN);
The problem begins when I have more items in the list and user has to scroll through them. Once background for an item is changed, The background color shows up on the newly visible items as I scroll. Also, the getChildAt(position) returns null (and hence a NullPointerException) when clicking again on the item.
Can anyone please help me with a simple code that helps me change background color of a list item?
Thanks in advance!
Sure thing. I would do this in the getView() method of a custom ListAdapter.
MyAdapter extends SimpleAdapter {
private ArrayList<Integer> coloredItems = new ArrayList<Integer>();
public MyAdapter(...) {
super(...);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = super.getView(position, convertView, parent);
if (coloredItems.contains(position)) {
v.setBackgroundColor(Color.CYAN);
} else {
v.setBackgroundColor(Color.BLACK); //or whatever was original
}
return v;
}
}
Update coloredItems when a list item is clicked.
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
if (coloredItems.contains(position)) {
//remove position from coloredItems
v.setBackgroundColor(Color.BLACK); //or whatever was original
} else {
//add position to coloredItems
v.setBackgroundColor(Color.CYAN);
}
}
If you are dealing with ListFragment then this code will be helpful,
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
if (view != null) {
getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
getListView().setDescendantFocusability(ListView.FOCUS_AFTER_DESCENDANTS);
catagoryValueListView=getListView();
catagoryValueListView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (ColoredView != null)
ColoredView.setBackgroundColor(Color.WHITE); //original color
view.setBackgroundColor(Color.BLUE); //selected color
ColoredView = view;
}
});
}
}
What I do is I create an xml file called i.e. list_background and put it in the drawable folder.
The xml looks like this:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/list_selected" android:state_pressed="true" />
<item android:drawable="#android:color/white" />
</selector>
And in the xml code for the ListView's item I put this xml as the items background i.e.
item.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="#style/Fill"
android:background="#drawable/list_background">
<!-- Your layout here -->
</RelativeLayout>
style=#style/Fill is only a short cut i made for
android:layout_height="match_parent" and android:layout_width="match_parent
Then in onListItemCLick:
public void onListItemClick(ListView l, View v, int position, long id) {
v.setPressed( !v.isPressed ) //Toggle between colors of the view
}
Simply you can do it like this in onListItemClick method
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
for (int a = 0; a < l.getChildCount(); a++) {
l.getChildAt(a).setBackgroundColor(Color.TRANSPARENT);
}
ColorDrawable colorDrawable1 = new ColorDrawable(
Color.parseColor("#A0A3A0"));
v.setBackgroundDrawable(colorDrawable1);
if (position == 0) {
Intent i = new Intent(MainActivity.this, NewActivity.class);
startActivity(i);
}
}
this is how I did it:
create a global variable View ColoredView; then when you setOnItemClickListener for your ListView, do this:
MenuList.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (ColoredView != null)
ColoredView.setBackgroundColor(Color.WHITE); //original color
view.setBackgroundColor(Color.BLUE); //selected color
ColoredView = view;
}
});
it's the simplest way in my opinion.
Thanks heycosmo. your solution solved my problem.
Have no clue why we should set background in 2 places.
1. Adapter's getView()
#Override
public View getView(int position, View convertView, ViewGroup parent) {
....
....
....
if(arrayBools[position]) {
view.setBackgroundColor(Common.colorBkgroundSelected);
}
else{
view.setBackgroundColor(Common.colorBkgroundNormal);
}
....
....
....
}
2. ListActivity's onListItemClick().
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
arrayBools[position] = ( arrayBools[position] ? false : true );
if(arrayBools[position]) {
v.setBackgroundColor(colorBkgroundSelected);
}
else{
v.setBackgroundColor(colorBkgroundNormal);
}
}