I have a Preference that enables a sync adapter, and takes a while to actually do its work when toggled. Consequently, when the user clicks the Preference, I spin off an AsyncTask to do the work. In the meantime, I disable the Preference and replace the check box with an indeterminate ProgressBar. I have all of this working via a hack involving a subclass of CheckBoxPreference that overlays the ProgressBar on top of the CheckBox. Yuck.
The android:widgetLayout attribute seems like it's designed exactly for this. I should be able to use android:widgetLayout to specify a replacement for the default CheckBox. Said replacement would implement Checkable and use a ViewSwitcher to switch appropriately between a CheckBox and a ProgressBar.
The only problem is that CheckBoxPreference, in its onBindView() method, seems to ignore the possibility that android:widgetLayout may be used. It explicitly does this:
View checkboxView = view.findViewById(com.android.internal.R.id.checkbox);
This effectively makes it impossible to swap in a custom Checkable via android:widgetLayout and have it actually work.
Is this an oversight/bug in CheckBoxPreference, or have I misunderstood android:widgetLayout? Is there a cleaner intended way to do what I'm trying to do?
First, I agree with you that Android should refactor the piece of code view.findViewById(com.android.internal.R.id.checkbox); to "calling a protected method" which can be overrided by subclass.
Luckily, we are still able to override work around as follows:
The idea is simple: declare a checkbox which has id is android default id #android:id/checkbox
<CheckBoxPreference
android:key="autostart"
android:widgetLayout="#layout/customlayout" />
and in customlayout.xml:
<SwitchView>
...
<CheckBox>
android:id="#android:id/checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="mycheck"
android:clickable="false"
android:focusable="false"
android:focusableInTouchMode="false"
</CheckBox>
It's really important to note that focusable attributes of checkbox must be set to false (I guess the default layout of CheckBoxPreference does the same thing) so that list apdater receives event rather than the checkbox itself.
I guess you didn't success in your try just because you didn't set the focusable state.
greensuisse
(https://sites.google.com/site/greensuisse/)
android:widgetLayout is the right part of the preference. In the CheckBoxPreference, the widgetLayout is the checkbox.
If you take a base Preference and put a ViewSwitcher in the widgetLayout, it should work
Related
See Screenshot
I want to change that text color of 'Enabled' to blue
Here is my xml
<SwitchPreference
android:defaultValue="false"
android:key="startScan"
android:summaryOff="#string/prefs_scan_startup_summary"
android:summaryOn="Enabled"
android:title="#string/prefs_scan_startup" />
Well... if noone else knows of a easy solution it might be tricky.
In general you could create a Sharedpreference listener that would update whatever property you want when the Switch state (and thus the SharedPreference) changes.
However I can't see a way to specifically change the textcolor of a SwitchPreference, so you might have to extend the SwitchPreference class and use your custom view where you would have access to the actual TextView to change its color.
See this for reference on extending that custom class.
I have spent more than 10 hours trying to get the animation of the switch to work.
I have tried so many things that I don't remember several of the attempts, but I'll explain those that I remember.
Code that should work (I think):
I use the widgetLayout parameter:
<CheckBoxPreference
android:defaultValue="false"
android:key="asd"
android:title="#string/asd"
android:widgetLayout="#layout/switchcompat_for_settings">
switchcompat_for_settings:
<android.support.v7.widget.SwitchCompat
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#null"
android:clickable="false"
android:focusable="false"
android:gravity="center"
/>
No animation.
Extending SwitchCompat with this code (best attempt??):
https://gist.github.com/antifriz/ad4412b72d50f63ec977
Going from false to true there is an animation, going from true to false there is no animation.
Non ideal behaviour (but acceptable, if it can't be prevented): if the value is true it plays animation when the activity is loaded.
Extending with following code:
Extending Preference classes in Android Lollipop = losing animation
No animation at all.
#Override
public boolean isShown() {
return getVisibility() == VISIBLE;
}
Using SwitchPreference:
Before Lollipop it has the old view, so not ideal because I would need different xml for before Lollipop and after.
If I have only one SwitchPreference I still have no animation. With several consecutive SwitchPreferences I get an animation in all but one (I've also checked with a new project with the Settings template and same problem).
Also, I prefer no animation in any Preference than animation in all but one.
Adding a second Switch:
In switchcompat_for_settings I add a second SwitchCompat and set the one with id=#android:id/checkbox to invisible. I extend the CheckboxPreference to override onBindView, and after calling super.onBindView I find the extra SwitchCompat and call setChecked to the appropriate value.
In the onPreferenceClick I call the setChecked of my extra switch.
It toggles without animation. My understanding is that the problem is that as onBindView is called A LOT of times (when creating the preference, and also each time I toggle it), it cancels the animation.
I tried to add a boolean to call setChecked in onBindView only after being called from onClick but did not succeed. Maybe it is the way to go and I did something wrong.
Only remaining idea (not willing to do this):
Add the switch manually to the activity root view, place in the correct position and handle from each activity that has this preference (several).
New to android and programming in general. This question might sound silly but I'd appreciate the answer. The question description and reasoning is at the beginning and the question is at the end of it all.
I want to apply a listener to a button in android. The way I understood from android.googlesource.com is that there is two way to do it:
applying an OnClickListener to the button in the activity.java
or
assign a method to my button in the xml layout using this
{#link android.R.attr#onClick android:onClick}
they gave the following xml layout example:
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="selfDestruct"
android:text="#string/self_destruct" />
plus the the code in activity.java
public void selfDestruct(View view) {
// Kabloey
}
android.googlesource.com
Questions:
According to this: {#link android.R.attr#onClick android:onClick} android.R.attr in the example are the following:
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="#string/self_destruct"
?
Does this:
android:text="#string/self_destruct"
android:onClick="selfDestruct"
mean that the button called self_destruct registered as a listener?
If I want to add more than one button listener in xml form how do I write it in the java document?
Thank you in advance
Really appreciate it.
Does this:
android:text="#string/self_destruct" android:onClick="selfDestruct"
mean that the button called self_destruct registered as a listener?
The button isn't "called" anything, it just has the text of the value for #string/self_destruct defined in the strings.xml file.
But, yes, the public void selfDestruct(View view) method is the method that will be called for the listener that is setup by the XML.
If I want to add more than one button listener in xml form how do I write it in the java document?
You can only set one click listener for a View.
Yes, layout_height, layout_width and text are attributes. You
can learn more about android attributes
here.
But keep in mind, that different views can use the same attributes
in different way.
It does not. The android:text attribute in this sample just refer to a string-resource called self_destruct to decide which text should be shown within the button. To distinguish views you can use android:id.
As already mentioned by other people, you are able to specify only one onClickListener using XML.
I'm creating my own personalized ListView by extending the ListView itself. This particular ListView shouldn't have scrollbars.
How can I disable the XML android:scrollbars attribute for my custom ListView?
I can't find a way to disable them programmatically. What am I missing?
The answer from dzeikei's will disable the scrollbars programmatically and ignore any value from android:scrollbars but what I'm really asking on 1. is how to make android:scrollbars an invalid attribute for my custom component.
Updated
OK as Richardo found out, seems like my original answer is the reverse way since the scrollbar is displayed internally :)
The correct way will be to call
super.setHorizontalScrollBarEnabled(false) and super.setVerticalScrollBarEnabled(false) in the constructor and override setHorizontalScrollBarEnabled() and setVerticalScrollBarEnabled() do nothing :D
Override isHorizontalScrollBarEnabled() and
isVerticalScrollBarEnabled() in your subclass to return false.
you could also override setHorizontalScrollBarEnabled() and
setVerticalScrollBarEnabled() for good measure.
Try keeping #null for android:scrollbars. Am not sure. But, I usually use #null when i want to remove anything from XML attributes.
This problem turned out to be much more tricky than it first appeared as it wasn't a problem on all but a few devices.
When creating a custom Preference by making it a subclass of Preference and also use a custom layout defined in an XML file in res/layout and use that layout in onCreateView() in the custom Preference it seems you completely loose the layout information the Preference-s normally have. Nothing strange with that, but if you still want a title (together with the new stuff), how do you specify the size of that title if you want it to be the same size as for other preferences? I was sure I had found the correct answer, setting textAppearance to textAppearanceLarge (either in the layout XML-file which seems like the better way or in the Java code in the Preference class) and this works fine on most devices.
This is from the custom Preference layout file:
<TextView
android:id="#+android:id/title"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
>
</TextView>
And this is from CustomPreference.onCreateView():
LayoutInflater mInflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
RelativeLayout layout = (RelativeLayout)mInflater.inflate(R.layout.custompreference, parent, false);
// Setting up new stuff
return layout;
This works and I can change the size of the title to Small or Medium and I need no Java code for the title in the custom Preference class. textAppearanceLarge is 22dp which seems to be the size of the Preference titles on most devices.
But on some, for instance the HTC Sensation an Desire S the Preference title is smaller. The title of the custom Preference comes out too large on these devices. So, the layouts for non custom Preferences clearly don't use textAppearanceLarge but something else.
My question now is: What do they use? Where can I get it for use in my custom Preferece? I have searched the Internet like crazy but I simply fail to find the answer. All examples I can find use textAppearanceLarge (or simply 22dp), probably because nobody has ever noticed that it doesn't always work correctly.
Use android:textAppearance="?android:attr/textAppearanceListItem"