Android NumberPicker deselect number - android

I have a slightly modified NumberPicker that I use and when the activity starts, the default value is already selected. This is annoying because it brings up the keyboard or brings up the dialog to cut/copy/paste. I did instruct the keyboard to stay down but it is still selected and will bring up the cut/copy/paste dialog. Once I scroll through the values the number is no longer selected and it acts normally. Does anyone know how to set the NumberPicker to not have anything selected at startup?
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
public class NumPicker extends NumberPicker
{
public NumPicker(Context context)
{
super(context);
}
public NumPicker(Context context, AttributeSet attrs)
{
super(context, attrs);
processAttributeSet(attrs);
}
public NumPicker(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
processAttributeSet(attrs);
}
/**
* Reads the xml, sets the properties
*/
private void processAttributeSet(AttributeSet attrs)
{
setMinValue(attrs.getAttributeIntValue(null, "min", 0));
setMaxValue(attrs.getAttributeIntValue(null, "max", 0));
setValue(4);
}
}
This is how it is used in the xml:
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_alignParentTop="true"
android:layout_marginRight="50dp"
android:layout_marginEnd="50dp"
android:layout_marginTop="40dp"
style="#style/CustomText"
max="100"
min="2"

The reason this happens is that the NumberPicker is the first (or only?) focusable element in your activity. You can trap the focus to your main layout view by adding this attribute to the root view:
android:focusableInTouchMode="true"

Related

Android ToggleButton drawing glitch on API 25

I'm facing this weird problem where I have a custom view (with custom drawing) overriding ToggleButton, and for some reason overriding the onDraw and draw methods do not prevent the parent class from drawing a part of it, which makes my view look like it's glitched.
This bug seems to be happening only with API level 25, on a physical device or on the emulator.
Using the following code for my custom toggle Button:
public class CustomToggleButton extends ToggleButton {
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
public CustomToggleButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
public CustomToggleButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public CustomToggleButton(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomToggleButton(Context context) {
super(context);
}
#Override
protected void onDraw(Canvas canvas) {
//nope, not drawing anything
}
#Override
public void draw(Canvas canvas) {
//nope, not drawing anything
}
}
And the following simple XML layout:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top|center_horizontal"
android:text="Bottom left: buggy custom ToggleButton.\nBottom right: regular ToggleButton." />
<test.com.togglebuttonbug.CustomToggleButton
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_gravity="bottom|left"
android:textOff="B"
android:textOn="A" />
<ToggleButton
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_gravity="bottom|right"
android:textOff="B"
android:textOn="A" />
</FrameLayout>
The result is the following:
If you look carefully at the screenshot, you can see that for the phone on the right, at the bottom left, instead of having nothing like the empty draw methods should do, you can see a piece of gray drawing.
Would anybody have an idea of what could be causing this? Is that a bug on Android N?

Android findViewById returns null, but only for my custom view

I have an activity with a button on it:
<Button
android:layout_height="match_parent"
android:layout_width="match_parent"
android:layout_alignParentTop="true"
android:id="#+id/some_id" />
and I can find it just fine from the activity's source:
button = (Button)findViewById(R.id.some_id); // returns the button
but if I switch the button for a custom control:
<FancyButton
android:layout_height="match_parent"
android:layout_width="match_parent"
android:layout_alignParentTop="true"
android:id="#+id/some_id" />
then I start getting null instead:
fancyButton = (FancyButton)findViewById(R.id.some_id); // returns null
Fancy button is really just an empty view at the moment, so I'm not sure what could cause it to fail like this:
public FancyButton(Context context, AttributeSet attrs) {
super(context);
LayoutInflater.from(context).inflate(R.layout.fancy_button, this, true);
}
I definitely missed something obvious.
I forgot to forward the attributes parameter to the base constructor. Since the id is an attribute, it ended up dropped on the floor instead of set.
Wrong:
public FancyButton(Context context, AttributeSet attrs) {
super(context);
Right:
public FancyButton(Context context, AttributeSet attrs) {
super(context, attrs);
Turning on "unused parameter" warnings would have caught this faster.

Custom preference not clickable

I added a custom preference to my project (code below). I added it to my preferences xml with a custom widgetLayout:
<w.PlusOnePreference
android:title="Rate App"
android:key="custom"
android:widgetLayout="#layout/plusone_pref"/>
Preference layout xml:
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.gms.plus.PlusOneButton
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:plus="http://schemas.android.com/apk/lib/com.google.android.gms.plus"
android:id="#+id/plus_one_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:focusable="false"
plus:size="standard" />
I see the layout and the button in the layout works fine. The only problem is that the preference isn't clickable. Like it's hidden behind something.
Any ideas on how to make it clickable?
If I add a regular Preference (without a widget layout) it works fine.
Thanks.
public class PlusOnePreference extends Preference {
private PlusClient mPlusClient = null;
public PlusOnePreference(Context context) {
super(context);
}
public PlusOnePreference(Context context, AttributeSet attrs) {
super(context, attrs);
}
public PlusOnePreference(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public void setPlusClient(PlusClient plusClient) {
mPlusClient = plusClient;
}
#Override
protected void onBindView(View view) {
super.onBindView(view);
//mPlusOneButton =
PlusOneButton plusOneButton = (PlusOneButton)view.findViewById(R.id.plus_one_button);
plusOneButton.initialize(mPlusClient, SettingsActivity.URL, SettingsActivity.PLUS_ONE_REQUEST_CODE);
}
}
in layout/plusone_pref.xml set android:focusable="false" for your Button
Putting Pskink's answer together with Ran's comment:
If your custom preference's layout is a ViewGroup (e.g. a *Layout), use android:descendantFocusability="blocksDescendants"
If it's just one View, use android:focusable="false"
Preferences don't have a clickable attribute, though there is an onClick() method. Tryandroid:selectable.

ScrollView disable focus move

I have a simple input form; it's a vertical LinearLayout with EditTexts inside a ScrollView.
<ScrollView android:layout_width="fill_parent"
android:layout_height="wrap_content">
<LinearLayout android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<LinearLayout android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="10dip"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView style="#style/Text"
android:text="Name"/>
<EditText style="#style/EditBox"/>
</LinearLayout>
<View style="#style/Divider"/>
<LinearLayout android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="10dip"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView style="#style/Text"
android:text="Password"/>
<EditText style="#style/EditBox"/>
</LinearLayout>
...
</LinearLayout>
</ScrollView>
When the user scrolls the form, it automatically moves its focus to the visible EditText.
It is possible to disable such behavior and always keep focus on the EditText currently selected by touch?
I understand that this may be a feature, but I need to disable it.
Thanks!
Just thought I'd share my solution to this. Even though some of the other answer's comments state that you cannot override this behavior, that is not true. This behavior stops as soon as you override the onRequestFocusInDescendants() method. So simply create your ScrollView extension to do this:
public class NonFocusingScrollView extends ScrollView {
public NonFocusingScrollView(Context context) {
super(context);
}
public NonFocusingScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public NonFocusingScrollView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) {
return true;
}
}
And you're done. The ScrollView will mess with your focus no more.
I have had such a problem too. The only way that helped me is to extend scroll view and to override neigher
#Override
public ArrayList<View> getFocusables(int direction) {
return new ArrayList<View>();
}
or
#Override
protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) {
return true;
}
but to override ViewGroup.requestChildFocus(View child, View focused) method as following:
#Override
public void requestChildFocus(View child, View focused) {
// avoid scrolling to focused view
// super.requestChildFocus(child, focused);
}
What worked for me was combining #dmon's and #waj's answers.
Only overriding onRequestFocusInDescendants() worked great when I was only dealing with EditTexts inside of the ScrollView, but when I started added multiple View types, it didn't work so well.
Only overriding getFocusables() did not work at all.
Overriding both onRequestFocusInDescendants() AND getFocusables() seems to work beautifully in all scenarios.
public class FixedFocusScrollView extends ScrollView {
public FixedFocusScrollView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public FixedFocusScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public FixedFocusScrollView(Context context) {
super(context);
}
#Override
public ArrayList<View> getFocusables(int direction) {
return new ArrayList<View>();
}
#Override
protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) {
return true;
}
}
I tried all solutions posted here but either didn't work on certain Android versions or it messed up with some other behavior like when switching between touch and non-touch mode (when you click buttons or use the trackpad).
I finally found that overriding the method getFocusables did the trick:
public class FixedFocusScrollView extends ScrollView {
public FixedFocusScrollView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public FixedFocusScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public FixedFocusScrollView(Context context) {
super(context);
}
#Override
public ArrayList<View> getFocusables(int direction) {
return new ArrayList<View>();
}
}
Try to cut the problem from the source (edit: i.e. move it to an XML file).
First, there must be a focusable element for that to happen. Make all focusable elements contained in that scroll into non-focusable elements. Make them focusable after the view is inflated and is visible.
android:focusable="false"
android:focusableInTouchMode="false"
I found another easy solution that works for my problem.
I got a ScrollView with an EditText at the top, and after it, a big list of TextViews, RatingBars and Buttons. The Buttons launch AlertDialogs, and when they pops up, the ScrollView moves to the top, to the EditText that is the one that still has the focus.
To solve it, I set in the onClick method of the Activity the requestFocusFromTouch() to the view clicked (in this case the Button).
public void onClick(View v) {
v.requestFocusFromTouch();
...
}
So now when I click on a Button, the ScrollView moves and put that Button on the center of the screen, that was just what I wanted.
I hope it help.
This method is very effective,you can overload computeScrollDeltaToGetChildRectOnScreen and return 0
public class NoScrollFocusScrollView extends ScrollView {
public NoScrollFocusScrollView(Context context) {
super(context);
}
public NoScrollFocusScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public NoScrollFocusScrollView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
protected int computeScrollDeltaToGetChildRectOnScreen(Rect rect) {
return 0;
}
}
For such behavior use nextFocusUp and nextFocusDown.
<EditText
android:id="#+id/my_edit_text"
android:nextFocusDown="#id/my_edit_text"
android:nextFocusUp="#id/my_edit_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</EditText>
Happened to me today, basically I was adding a View programmatically between some existing views, and Scroll automatically moved to focus that view. What I just did, is the following:
container.setFocusable( false );
This solved the issue for me. It may not be applicable in all situations, but works well for mine where the scrolling is done programmatically:
View originalFocus = getCurrentFocus();
scroller.fullScroll(View.FOCUS_DOWN);
if (originalFocus!=null) {originalFocus.requestFocusFromTouch();}

Implement a RadioButtonPreference in Android

How can you implement a RadioButtonPreference in android? Just like the CheckBoxPreference.
Are there any workarounds?
Use a ListPreference. You need to have more than one radio button for it to be meaningful (otherwise, it would just be a checkbox).
If, for some reason, you do not want to use a ListPreference, grab the source code to CheckBoxPreference from the Android open source tree and roll your own Preference implementation. You should then be able to list your custom implementation in preference XML using the namespace (e.g., com.foo.RadioButtonPreference).
You can use a custom class extending from CheckBoxPreference like this:
public class RadioButtonPreference extends CheckBoxPreference {
public RadioButtonPreference(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setWidgetLayoutResource(R.layout.preference_widget_radiobutton);
}
public RadioButtonPreference(Context context, AttributeSet attrs) {
super(context, attrs);
setWidgetLayoutResource(R.layout.preference_widget_radiobutton);
}
public RadioButtonPreference(Context context) {
this(context, null);
}
#Override
public void onClick() {
if (this.isChecked()) {
return;
}
super.onClick();
}
}
Then create a preference_widget_radiobutton.xml layout file:
<?xml version="1.0" encoding="utf-8"?>
<!-- Layout used by CheckBoxPreference for the checkbox style. This is inflated
inside android.R.layout.preference. -->
<RadioButton android:id="#+android:id/checkbox"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:clickable="false"
android:focusable="false"/>

Categories

Resources