I have an extended BaseAdapter that has LinearLayout children (an ImageView and a TextView in each) hooked up to a custom Gallery.
When I first launch my Activity, I want to call setSelection(position) to cause the ImageView to change its selector to the "selected" image. This works once I fling the Gallery, on subsequent selected children, but not the very first time the app is launched.
My selector:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true"
android:drawable="#drawable/home_image_select" />
<item android:state_selected="false"
android:drawable="#drawable/home_image" />
</selector>
My first guess was to call notifyDataSetChanged() on the adapter after calling setSelection(), which I attempted to do like this:
((CustomAdapter) gallery.getAdapter()).notifyDataSetChanged();
That didn't do anything. I also tried overriding the setSelection() of the Gallery class to do this:
View v = this.getAdapter().getView(position, null, this);
((ImageView) v.findViewById(R.id.gallery_image)).setSelected(true);
That doesn't work either. Anything I'm missing or could try?
I found the solution to my own problem by overwriting the setSelection() of Gallery (it worked after all).
#Override
public void setSelection(int position) {
super.setSelection(position);
View v = this.getAdapter().getView(position, null, this);
v.setFocusable(true);
v.requestFocus();
}
I think you should not call notifyDataSetChanged(), selection state will be cleared when underlying dataset changed.
Just call setSelection(position), it works in my app.
Related
I'm willing to create a android quiz app. I've done all things and my app is completed but I'd like to make the quiz option buttons to change its color when it is pressed by user in order to show whether the answer is correct or wrong.
I'd like to show red color button on clicking wrong option and green on correct option .please help me with a simple code that I can embedd in my presaved app java files.
You can try this:
someButton.setBackgroundColor(Color.RED); // Wrong option
someButton.setBackgroundColor(Color.GREEN); // Correct option
Refer to View#setBackgroundColor(int) and Color.
A Button is a sub-class of View.
You can use the combination of android:state_selected and the android:state_enabled properties of the StateListDrawable to achieve the effect through xml.
Your button background can be defined as a drawable below
<selector>
<item android:drawable="#drawable/default_button_background" />
<item android:state_selected="true" android:state_enabled="true" android:drawable="#drawable/correct_answer_background" />
<item android:state_selected="true" android:state_enabled="false" android:drawable="#drawable/wrong_answer_background"
</selector>
and in your code. On Click of the button add this code
boolean isAnswerCorrect = //your logic to check if answer is correct or not
clickedButton.setEnabled(isAnswerCorrect);
In the following approach, you would need to create two image files for backgrounds on the button to represent correct or false.
Create a folder called Drawable under res and place these two image files in there, then call them as seen below like, R.drawable.filename.
buttonCheckAnswerObject = (Button)findViewById(R.id.buttonCheckAnswer);
buttonCheckAnswerObject.setOnClickListener(new OnClickListener() {
#Override
public void onClick(final View v) {
boolean userAnswer;//check if correct
if (userAnswer){
v.setBackgroundResource(R.drawable.button_correct_answer_color);
}
else {
v.setBackgroundResource(R.drawable.button_false_answer_color);
}
}
});
enter code here
Background
Lollipop introduces a new way to transition between activities (links here, here, here and here) .
The problem
They said on one of the videos (here) that I can choose exactly how each view will transition, but I can't find how to do it. The only thing I've found is how to set it for all views, except for the "hero" view (which you choose how to transition it to the new activity and back).
For example, let's take the Google Now app, which has this screen:
when you click on the editText, the bottom cards have the "explode" effect, but everything darkens and the imageView behind the editText fade out.
The editText is probably the "hero" view, which transitions between the activities, and because it's on the same location on the screen, this probably doesn't have any visual effect for the user.
What I've tried
I've tried to mimic what Google now did, but as I've written, the imageView also has the "explode" effect, so it goes to the bottom, behind the listView, which is a weird effect (since it gets cropped while animating). I'd prefer it to either animate to a different direction, or just fade out.
Here's a sample code of the transition I'm using:
final Intent intent = new Intent(activity, SearchActivity.class);
ViewCompat.setTransitionName(viewToTransitionFromAndTo, VIEW_TO_TRANSITION_TO);
final ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(activity,
viewToTransitionFromAndTo, VIEW_TO_TRANSITION_TO);
ActivityCompat.startActivityForResult(activity, intent, requestCode, options.toBundle());
in the theme of the activity that starts the other activity, I have this:
<style name="AppTheme.transition" parent="#style/AppTheme">
<!-- transition support -->
<item name="android:windowContentTransitions" tools:targetApi="21">true</item>
<item name="android:windowActivityTransitions" tools:targetApi="21">true</item>
<item name="android:windowEnterTransition" tools:targetApi="21">#transition/explode</item>
<item name="android:windowExitTransition" tools:targetApi="21">#transition/explode</item>
<item name="android:windowSharedElementEnterTransition" tools:targetApi="21">#transition/move_image</item>
<item name="android:windowSharedElementExitTransition" tools:targetApi="21">#transition/move_image</item>
<item name="android:windowAllowReturnTransitionOverlap" tools:targetApi="21">true</item>
<item name="android:windowAllowEnterTransitionOverlap" tools:targetApi="21">false</item>
</style>
and the transition files are:
explode.xml
<?xml version="1.0" encoding="utf-8"?>
<explode />
move_image.xml
<?xml version="1.0" encoding="utf-8"?>
<transitionSet>
<changeBounds />
<changeImageTransform />
</transitionSet>
The question
How can I choose what each view will do upon transition, instead of just saying everything to have the same effect (except for the "hero" view) ?
For example, is it possible to choose "explode" transition for all views except for the "hero" view , and a view that will have a different transition (fade out/in, for example) ?
Please show an example of how to do it. You can use the code I've written above if needed.
Use a TransitionSet and add/exclude certain targets using Transition#addTarget() and Transition#excludeTarget(). For example, let's say you have two views and you want each of them to slide off the screen in different directions. You could create such a transition using the following code:
TransitionSet set = new TransitionSet();
Transition slideUp = new Slide(Gravity.UP);
slideUp.addTarget(view1);
set.addTransition(slideUp);
Transition slideDown = new Slide(Gravity.DOWN);
slideDown.addTarget(view2);
set.addTransition(slideDown);
TransitionSet extends Transition, so the resulting set object can then be used as the window content transition, which will play the two slide transitions simultaneously in parallel.
I'm trying to figure out how to do this thing for an android app.
So I made an array of buttons
Button btn[][] = new Button[10][10];
How do I make it so that once I click a button that it, for instance, turns a different color?
I have had trouble making it because I can create the array, and it looks nice, but how do I assign different functions for individual buttons? Are buttons in the array already labeled and can I use individual ones? Thanks.
Any time you would like to make a view change a different color based on the user actions, you should use a state list drawable
Here is a very simple example of a state list drawable which you would use to trigger only off whether the user had pressed the view or not.
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="false" android:color="#color/brown" />
<item android:state_pressed="true" android:color="#color/brown_selected" />
</selector>
You would then set this on the view with the following attribute to the view in xml
android:background="#drawable/background"
This though, will only be changed while the user is pressing the button. If you would like it to permenantly change color, use a on click listener. For example if you would like to change the background color to white:
button.setOnClickListener(new View.OnClickListener() {
/**
* Handle a user clicking on the view v
* #param v the view the user clicked on. In this case the button
*/
#Override public void onClick(View v) {
// Set the background color to white
v.setBackgroundColor(Color.WHITE);
}
});
I am having a list in my android application. The list items are custom objects and depending on the custom object property, list item color will be decided.
Now the problem is, when I select any item for such list, List selector is not displayed.
How can I fix this issue? To set list item color, I am using following method in adapter.
convertView.setBackgroundColor(Color.LTGRAY)
Is this the right way to set color? if not what else I can use.
Thanks in advance.
Swapnil Dalal.
You can fix this by two ways:
1.Write a selector for the itemview which set the background to the transparent in the pressed state, then set the selector as the backgound of the itemview.
<item android:state_enabled="true"
android:state_pressed="false"
android:drawable="#color/gray" />
<item android:state_enabled="true"
android:state_pressed="true"
android:drawable="#color/transparent" />
2.Remove the listselector, just write a selector for the itemview with the color you wanted by the different state and set it as the background of the itemview.
Please add your getView method code so that we can help you better. One common mistake we do is that we don't always create new view for each item in the list view for loading different layout list Items.
For example common approach for identical itemed list:
if(view == null)
{
vi = inflater.inflate(R.layout.fb_list_row, parent, false);
}
While for different object listview items you need to remove if statement like this;
vi = inflater.inflate(R.layout.fb_list_row, parent, false);
and then do the changing for each list item..
Hope this will help. Else put some more code.
I got solution for this question,
I created to different xml files for different objects in the application.
So in the getView of adapter, depending on condition we can load either one of the xml.
Example:
`if(true) {
convertView.setBackgroundResource(R.drawable.firstxml);
}
else {
convertView.setBackgroundResource(R.drawable.secondxml);
}`
In these xmls, we can specify colors as required.
Example:
<?xml version="1.0" encoding="utf-8"?>
<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_enabled="false"
android:drawable="#color/transperent"/>
<item
android:state_pressed="true"
android:state_enabled="true"
android:drawable="#drawable/listview_selector" />
</selector>
Thanks,
Swapnil Dalal.
I want to be able to see what items that have been selected in my list. Before turning ListView into ListFragment, the selected items had a blue background color (Holo Dark), but now I can only see the blue color while pressing the items - then it disappears. I do not have a problem with the items getting "checked", because they are. You just can't see it.
Here's what I do in onActivityCreated():
getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
getListView().setItemsCanFocus(false);
getListView().setMultiChoiceModeListener(new LongPress());
LongPress() is a private class implementing ListView.MultiChoiceModeListener. It opens up a contextual action bar when holding finger on an item. The user can then select more items, and this is where the problem occurs. You can not see which items are checked or not (I want them to be highlighted). Why did it work before extending ListFragment? I tried to create a custom selector in my .xml-files, that didn't seem to work either. I would prefer using the custom one, if there's any.
Here's another method in my ListFragment class:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_listview, container, false);
}
fragment_listview.xml isn't doing anything special apart from changing the background color and the color of the divider.
What should I do?
I tried this, but it didn't work:
In my list_item.xml:
android:background="#drawable/selector"
selector.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true"
android:drawable="#drawable/item_checked" />
</selector>
item_checked.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http//schemas.android.com/apk/res/android" >
<solid android:color="#000000" />
</shape>
I was having the exact same issue.
I found a solution in this post: Highlight custom listview item when long click
The trick:
Set in the layout file of your list's row (in the top level component, usually a LinearLayout or RelativeLayout):
android:background="?android:attr/activatedBackgroundIndicator"
I cannot find the details right now, but you have to provide a statelist drawable for the listview-items that provides a separate drawable for the checked state.