I'm using the following selector to change set a row's background when it is selected
<item android:state_activated="true" android:drawable="#drawable/row_sel" />
<item android:drawable="#drawable/row_neut"/>
It works fine when a row is phyiscally clicked. All I want to do is programatically set a row to be selected. I thought this would be trivial, but after over an hour of trying and googling, I can't find an answer.
Things I've tried:
listView.setSelection(0)
listView.setItemChecked(0)
listView.getItem(0).setActivated(true) //fails: getChildCount() is 0
adapter.notifyDataSetChanged(), listView.invalidate() //out of desperation
I could obviously use a hack within the adapter (i.e assign selected/neutral Drawable each time) but I'd rather have it clean.
You can use this,
listView.performItemClick(listView, position, listView.getItemIdAtPosition(position));
USer listView.setSelection(0);
and if you want a background color for a listview selected, you could use Transition
Related
I recently refactored my App to use the jetpack navigation. On my MainActivity, I had a ViewPager containing 3 fragments with 1 recyclerview each. I therefore moved the ViewPager from the Activity to a new Fragment. Everything works when it comes to the functionality itself, but a new issue arose which really bugs me: When I select an item on the recyclerview with a long press, the ripple effect gets stuck and stays there, as if I'm still pressing the item, which I don't. Here is a picture of a selected item. As it can be seen, the ripple effect stays active on the TextView.
When I unselect the Item, the ripple effect also stays active:
The selection itself is handled with the android SelectionTracker. The TextView has the background set to background="?android:attr/selectableItemBackground". The whole ViewItem has the background set to android:background="#drawable/bg_multi_selection, whereas the bg_multi_selection file looks as follows:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/secondaryLightColor" android:state_activated="true" />
<item android:drawable="#android:color/transparent" />
</selector>
What could be the issue of that? This is especially weird, as the problem did not exist, when the ViewPager with its fragments was contained inside the Activity, and not a Fragment. Any suggestions on how to fix this?
I found a solution which works for me. So for anyone interested, I did the following:
In the recyclerviewadapter in the onBindViewHolder() method I check if the element is selected and additionally set the background color and background resource of the TextView programmatically.
if (elementIsSelected) {
viewHolder.viewBinding.itemTextView.setBackgroundColor(context.resources.getColor(R.color.transparent, context.theme))
} else {
val outValue = TypedValue()
context.theme.resolveAttribute(android.R.attr.selectableItemBackground, outValue, true)
viewHolder.viewBinding.itemTextView.setBackgroundResource(outValue.resourceId)
}
whereas I definied the color to be transparent, i.e. #00000000
It's odd that this problem occurs only on some devices, so I'm not sure if the "real" problem lies somewhere else, but at least that's how I fixed it. Hope that might be helpful for someone else.
Not surprising I found myself looking at a tablet-optimized design one day that showed a pane with search results on the left side and a pane to display corresponding details on the right. The results on the left pane had a selected state to indicate which details were currently shown. What seemed to be a walk in the park ended up being a tiresome journey of trial and error. But finally I managed to get it working and I removed all irrelevant test-code only to discover it had stopped working straight away. I reintroduced the "irrelevant" part and surprisingly it worked as planned.
Client happy, designer happy, but not me, because I still don't understand why it works as it does.
I have a fragment that has a ListView with choiceMode set to ListView.CHOICE_MODE_SINGLE.
The adapter inflates custom views for each result and sets a drawable as background (happens in code)
The drawable is a selector wrapped in a RippleDrawable and has checked and activated states with a drawable for the selected state that needs to be preserved.
The custom view overrides setSelected(boolean selected) and dependent on the boolean adds or removes a view that has the selected state.
Now my problem is 3 & 4. Having the checked and activated states (step 3) ensures that setSelected(true) gets called when the view is tapped, but not immediately gets called again with setSelected(false) once the touchDown ends and thus the view I set in step 4 stays.
I had however expected I didn't need this custom view from step 4 as I thought it would use the drawable for the activated state from step 3. Removing the custom (thus unrelated to Android states system) view from step 4 has the effect that the state drawable from step 3 does show up, but only during onPress (touchDown/Hold) and... on the previous selected item!
Item Background
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#color/light_gray">
<item android:drawable="#drawable/search_result_selector" />
</ripple>
Selector Drawable (search_result_selector)
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/white_selected" android:state_selected="true"/>
<item android:drawable="#color/white_selected" android:state_pressed="true"/>
<item android:drawable="#drawable/search_result_highlighted_state" android:state_activated="true"/>
<item android:drawable="#drawable/search_result_highlighted_state" android:state_checked="true"/>
<item android:drawable="#color/white"/>
</selector>
setSelected(selected) on custom view used for items in ListView
#Override
public void setSelected(boolean selected) {
super.setSelected(selected);
if (selected && selectedView == null) {
selectedView = new View(getContext());
selectedView.setBackground(Utils.getDrawable(getContext(), R.drawable.action_bar_background));
RelativeLayout.LayoutParams lp = new LayoutParams(Utils.pxFromDp(getContext(), 3), getHeight());
lp.addRule(ALIGN_PARENT_RIGHT);
addView(selectedView, lp);
} else if (!selected && selectedView != null) {
removeView(selectedView);
selectedView = null;
}
}
selectedView is a field I defined in my custom view class. I understand why it works, but I wonder why I need it as I expected the state drawable to be used correctly and preserve selection. The strange thing is when I remove that part, the ListView decides to do use the drawable, but on the previous selected view and only during touchDown. Now why would the presence of a custom implementation, not tied to any Android API influence the working of Android's view states? Apparently it is tied somehow, somewhere, but I fail to see where. Any pointers to the why behind this all would put my mind at ease. Thank you in advance!
EDIT
Apparently one of my conclusions was wrong. setSelected(false) was called, even with the states in the selector. Which makes sense perhaps if activated is the state that matters. I moved the code to an overriden method on setActivated, which does in fact show my custom view. That said the weirdness remains... the state drawable don't work as expected.
how i add icon to spinner by xml where find the default value (not in the the list) ??
<Spinner
android:id="#+id/spinner1"
android:layout_gravity="center"
android:layout_weight="0.28"
android:prompt="#string/language_prompt"
android:textSize="12sp" <!-- icon insten of text -->
/>
i try android:Background="#drawable/world_language_icon" but doesn't work.
i dont find src or set drawable .
I dont find here (in google)
i need xml and not javaalso here i find in java
First of all, you should probably try proof reading your question before posting, and make sure you know exactly what you want to know.
how i add icon to spinner by xml
The icon is not added to the spinner itself, as what you use to populate the Spinner is an adapter. In order to add an icon to your Spinner items, you would need to create a custom adapter to set to the Spinner, and use a custom layout for the List Items.
where find the defult value (not in the the list) ??
That, I'm not sure what you are asking for. If your question is how to set a default item/value for the Spinner, it's not possible. The default item set will always be the first item on the List you populate the Spinner with. You can of course automatically select a different Spinner item in code, but even then you'll notice that the first item was selected before your other actions.
I have a list with items, some items can be in 'viewed' status. i want those items to have different background color then the rest.
list view basically has a single selector for the whole list, setting a background color on one of the items prevent wont do the trick since the selector is drawn below my item's layout as background and counts on them being transparent.
is there a way to define more then one selector for a list ? if not is it possible to create a selector that has an extra state ? basically all i want is the regular list selector plus an extra state that it's ColorDrawable is defined in my colors.xml.(since i can't inherit from a drawable and the list_selector drawables of android are not visible in the SDK for me to use i wanted just to add a state, but then how do i enforce using the extra state ?)
Found the answer.
My problem is not the state of the selector, i want the selector in the same state for ALL items!
the problem is that i want the item to be regular if certain boolean in items in the adapter is false and color X if the boolean is true, but even if the color is X i still want it to be transparent once it's selected or pressed.
So the solution is the following xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:drawable="#android:color/transparent" /> <!-- pressed -->
<item android:state_selected="true"
android:drawable="#android:color/transparent" /> <!-- focused -->
<item android:drawable="#color/viewed_hotels_color" /> <!-- default -->
</selector>
i found out the even though the list itself is the one that gets the state , it DOES pass the state on to it's children (I.E the list items) which i thought it didn't do.
Only android:focused wont be effective here, android list items are not focused but selected... so as you can see in any state that is not pressed or selected i give my default color, otherwise it's transparent and the selector is visible to all.
in my adapter i need the following code(in getView() method):
View itemView = convertedView; <- i'll spare you the layout details...
Item item = getItem(position);
if( item.isViewed() ){
itemView.setBackgroundResource(R.drawable.viewed_item_background);
}else{
itemView.setBackgroundDrawable(null);
}
this makes sure every item will get the right background. of course if an item state is changed to viewed and i want it to show i need to call notifyDatasetCahnged() on the adapter.
You can implement a custom subclass of your Adapter and override the method getView(). As this method is called by the list to get the View for a single item you can define how the a single list item looks like by overriding getView(). So changing the background color of an already viewed item shouldn't be a problem.
UPDATE
The AbsListView class which the ListView class extends has a method called setDrawSelectorOnTop(). I think you can use it to control the behavior of the selector.
I have a linear layout in which each row is inflated programatically and I want the rows to behave like the ListView when clicked on. That is, I want the row to highlight in the exact same way/colour that the default ListView does. How would I go about doing this?
Ok I have finally figured out how to do this...basically it is done using a selector like the color selector linked by style except instead of 'color' use a drawable for the states and you can refer to the default list drawable that is used in ListView by this:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:drawable="#android:drawable/list_selector_background" />
</selector>
and using this xml as the background for my View.
All the public default drawables can be found here: http://developer.android.com/reference/android/R.drawable.html
I was able to do the same with a text view that I wanted to behave like a list item by using:
<Textview
....
android:background="#android:drawable/list_selector_background"
/>
This might be a good place to start looking.
Although, i would advise you to use the ListView itself, rather than implementing it again.
if you still have a problem with that then please remember that some of UI elements are not clickable (RelativeLayout), so you have to add one more line:
<RelativeLayout
....
android:clickable="true"
...
To your listview set property
android:listSelector="#color/test"
and this test color set any transparent color you like. you can create any transparent color by using hex transparent color