Text cursor invisible for custom EditText - android

Help needed! I created a custom textbox for input. Keys append fine as I click through the keypad. However for some reason the text cursor is not showing up. What can I possibly missed? Pls advice.
p.s I tried editText.setCursorVisible(true)
I also considered the possibility that the cursor is having the same color as the background..
public class ETEditText extends EditText {
public ETEditText(Context context) {
super(context);
}
public ETEditText(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ETEditText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
public boolean onCheckIsTextEditor() {
return false;
}
}
I found that it was actually because I return false on the onCheckIsTextEditor()
but if I make it true I will make the software keyboard show up.. I want to hide it all the time though
any suggestions?

It was actually because false was returned for the onCheckIsTextEditor()
That was done by the original developer for suppressing the keyboard, which is not a good idea since
it suppresses the cursor as well

Related

android: visual issues on a custom slider

I created a custom slider that was working fine, but suddenly it started showing visual issues and i have no idea where to look to solve this problem.
the issue is the appearance of black borders/gradients around it. i tested on android 6 and android 4.0.3 as well. both are showing the same problem. on android 4.0.3, i can also see this problem around the actions in the toolbar when i press on them, it makes like a black gradient shadow.
any idea?
the code of my slider is:
public class StyledSeekBar extends SeekBar {
public StyledSeekBar(Context context) {
super(context);
this.init();
}
public StyledSeekBar(Context context, AttributeSet attrs) {
super(context, attrs);
this.init();
}
public StyledSeekBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.init();
}
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
public StyledSeekBar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
this.init();
}
/**
* Initializes the instance of this class.
*/
private void init(){
setThumb(getResources().getDrawable(R.drawable.apptheme_scrubber_control_selector_holo_light));
setIndeterminateDrawable(getResources().getDrawable(R.drawable.apptheme_scrubber_progress_horizontal_holo_light));
setProgressDrawable(getResources().getDrawable(R.drawable.apptheme_scrubber_progress_horizontal_holo_light));
}
}
it's no shadow. Looks like .png stretched. Try 9png
I found the solution! To fix this kind of issue, it is necessary to verify the 9-patch images and resolve all the bad patches. This can be done by using the draw9patch tool.

Extending Preference classes in Android Lollipop = losing animation

Just for extending CheckBoxPreference or SwitchPreference on Android Lollipop, the widget (the checkbox or the switch) won't have animation anymore.
I'd like to extend SwitchPreference to force api < 21 to use SwitchCompat instead of the default one they are using (which is obviously wrong).
I am using the new AppCompatPreferenceActivity with appcompat-v7:22.1.1 but that doesn't seem to affect the switches.
The thing is that with just extending those classes, without adding any custom layout or widget resource layout, the animation is gone.
I know I can write two instances of my preference.xml (on inside values-v21) and it will work... But I'd like to know why is this happening and if somebody knows a solution without having two preference.xml.
Code example:
public class SwitchPreference extends android.preference.SwitchPreference {
public SwitchPreference(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
public SwitchPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
public SwitchPreference(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SwitchPreference(Context context) {
super(context);
}
}
This or the same for CheckBoxPreference and then using:
<com.my.package.SwitchPreference />
Will make the animation in a Lollipop device to be gone.
--
Another thing I tried for the SwitchPreference (that I can with CheckBoxPreference) is to give a layout with the default id but #android:id/switchWidgetis not public while #android:id/checkbox is. I also know I can use a <CheckBoxPreference /> and give a widget layout that is in fact a SwitchCompat, but I'd like to avoid that (confusing the names).
It seems I found a fix for your issue.
Extensive Explanation
In SwitchCompat, when toggling the the switch, it tests a few functions before playing the animation: getWindowToken() != null && ViewCompat.isLaidOut(this) && isShown().
Full method:
#Override
public void setChecked(boolean checked) {
super.setChecked(checked);
// Calling the super method may result in setChecked() getting called
// recursively with a different value, so load the REAL value...
checked = isChecked();
if (getWindowToken() != null && ViewCompat.isLaidOut(this) && isShown()) {
animateThumbToCheckedState(checked);
} else {
// Immediately move the thumb to the new position.
cancelPositionAnimator();
setThumbPosition(checked ? 1 : 0);
}
}
By using a custom view extending SwitchCompat, I found out, that isShown() always returns false, because the at third iteration of the while, parent == null.
public boolean isShown() {
View current = this;
//noinspection ConstantConditions
do {
if ((current.mViewFlags & VISIBILITY_MASK) != VISIBLE) {
return false;
}
ViewParent parent = current.mParent;
if (parent == null) {
return false; // We are not attached to the view root
}
if (!(parent instanceof View)) {
return true;
}
current = (View) parent;
} while (current != null);
return false;
}
Interestingly, the third parent is the second attribute passed to getView(View convertView, ViewGroup parent) in Preference, means the PreferenceGroupAdapter didn't get a parent passed to its own getView(). Why this happens exactly and why this happens only for custom preference classes, I don't know.
For my testing purposes, I used the CheckBoxPreference with a SwitchCompat as widgetLayout, and I also didn't see animations.
Fix
Now to the fix: simply make your own view extending SwitchCompat, and override your isShown() like this:
#Override
public boolean isShown() {
return getVisibility() == VISIBLE;
}
Use this SwitchView for your widgetLayout style, and animations work again :D
Styles:
<style name="AppTheme" parent="Theme.AppCompat.NoActionBar">
…
<item name="android:checkBoxPreferenceStyle">#style/Preference.SwitchView</item>
…
</style>
<style name="Preference.SwitchView">
<item name="android:widgetLayout">#layout/preference_switch_view</item>
</style>
Widget layout:
<de.Maxr1998.example.preference.SwitchView
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" />
Sometimes Extending from a Class is not the best solution. To avoid loosing the animations you could instead Compose it, I meant creating a Class where you have a SwitchPreference field variable and apply the new logic to it. It's like a wrapper. This worked for me.
i manage to fix it like this and animations is working before it was going to the state directly without animation:
FIX:
CustomSwitchCompat.class
public class CustomSwitchCompat extends SwitchCompat {
public CustomSwitchCompat(Context context) {
super(context);
}
public CustomSwitchCompat(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomSwitchCompat(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#Override
public boolean isShown() {
return getVisibility() == VISIBLE;
}
}
In your layout do this: preference_switch_layout.xml
<com.example.CustomSwitchCompat
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#android:id/checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#null"
android:clickable="false"
android:focusable="false"
app:switchMinWidth="55dp"/>
and in your preference.xml do this:
<CheckBoxPreference
android:defaultValue="false"
android:key=""
android:widgetLayout="#layout/preference_switch_layout"
android:summary=""
android:title="" />
I was having this issue, when I was using custom layout (app:layout) for SwitchPreference. At first, switch animation was triggered, but after a little scrolling it stopped and switch was jumping without animation. I tried every solution from stackoverflow, but nothing helped.
After debugging of SwitchCompat.setChecked method I found out that this condition is failing:
public void setChecked(boolean checked) {
...
if (getWindowToken() != null && ViewCompat.isLaidOut(this)) {
animateThumbToCheckedState(checked);
} else {
// Immediately move the thumb to the new position.
cancelPositionAnimator();
setThumbPosition(checked ? 1 : 0);
}
}
Concretely ViewCompat.isLaidOut(this) returned false. I guess this is a bug either in View or Preference (or subclasses). Anyway, I was able to fix this with little hack.
I created a subclass of SwitchCompat and did override setChecked method, where I call requestLayout() and in onNextLayout I call SwitchCompat's setChecked method. This guarantees that isLaidOut condition is true when changing checked state.
Full code of custom SwitchCompat:
class SwitchCompatFix #JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = androidx.appcompat.R.attr.switchStyle,
): SwitchCompat(context, attrs, defStyleAttr) {
override fun setChecked(checked: Boolean) {
doOnNextLayout {
post { super.setChecked(checked) }
}
requestLayout()
}
}
public class SwitchPreference extends android.preference.SwitchPreference {
public SwitchPreference(Context context) {
this(context, null);
}
public SwitchPreference(Context context, AttributeSet attrs) {
this(context, attrs, android.R.attr.checkBoxPreferenceStyle);
}
public SwitchPreference(Context context, AttributeSet attrs, int defStyleAttr) {
this(context, attrs, defStyleAttr, 0);
}
public SwitchPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
try {
Field canRecycleLayoutField = Preference.class.getDeclaredField("mCanRecycleLayout");
canRecycleLayoutField.setAccessible(true);
canRecycleLayoutField.setBoolean(this, true);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}

Pressing ChildView behaves as if ParentView is clicked

I found a weird behavior on Android.
Let's say I have a list View and each row is a Linear layout containing a textView.
I set a longClickListener on the listView. Also, I set an onTouchEvent on the textView.
The behavior I want is that if the user press the textView in the list, onTouchEvent should be run. If the user Long-presses outside the textView, it should perform what's defined in the longClickListener.
However, in Android 4.2.1, this behavoir doesn't seem to work.
I found that Google changed the code so that ChildView shares pressed state from its parent view in Jelly Bean. Is this right?
If this is the case, how can I implement the way I want?
On other words, I want the childView and parentView behave independently!!
Any answer would be appreciated!
Below is my CustomTextView.java
public class CustomTextView extends TextView {
public CustomTextView(Context context) {
super(context);
setPressed(false);
}
public CustomTextView(Context context, AttributeSet attrs) {
super(context, attrs);
setPressed(false);
}
public CustomTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setPressed(false);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
Intent.... something
Start a new activity... pretty straightforward
return super.onTouchEvent(event);
}
}
Below is the textview of my list_item.xml
<com.keek.widget.CustomTextView
android:id="#+id/caption"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/thumbnail_overlay"
android:lineSpacingExtra="1dp"
android:textColor="#android:color/black"
android:textSize="#dimen/text_11"
android:duplicateParentState="false"
android:longClickable="false"
android:textColorLink="#color/linkify_blue" />
My list is pretty straightforward. It is a plain listView with onLongClickListener which opens a dialog box.
The this is that when I press the textView, both the dialogbox and new activity open at the same time. What I want is that when I press textView, it should open a new activity only not a dialog.

Android: Open Sliding Drawer in Graphical Layout in Eclipse?

Is it possible to open a SlidingDrawer when viewed inside the Eclipse graphical layout preview? By default it's closed when viewed so I cannot see what is happening with the layouts inside the SlidingDrawer.
If this isn't possible, what would be the best way to handle this problem? A separate layout file I guess?
I am not sure if there is a standard way to do this.
I currently use the following method: override SlidingDrawer.onFinishInflate() to force it open when in Eclipse layout preview.
import android.widget.SlidingDrawer;
public class MySlidingDrawer extends SlidingDrawer {
public MySlidingDrawer(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public MySlidingDrawer(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
protected void onFinishInflate() {
super.onFinishInflate();
if (isInEditMode()) {
open();
}
}
}
Then, of course, replace SlidingDrawer by my.package.MySlidingDrawer in layout.xml.

android: how to set custom font for entire application

I have developed a very huge application and now i have a requirement of having custom font for all controls in the application. so I want to know the better way to change the font in one shot. The application has more than a hundred XML layout. and i cant change all controls to a custom component with custom font. Please provide a solution to Change the font without altering all the controls in XML.
Do something like this
pacage com.prac;
class MyFontedTextView extends TextView {
public FontedTextView(Context context) {
super(context);
init();
}
public FontedTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public FontedTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
String otfName = "MyCustomOtfFileWhichIPutInAssetsFolder.otf";
Typeface font = Typeface.createFromAsset(context.getAssets(), otfName);
this.setTypeface(font);
}
}
Now replace this all over in xml file from your TextViews
<com.prac.MyFontedTextView .... instead of <TextView
This change you have to do all over for it to apply
also for the case of button text . Button is also subclass of TextView
So the same can work for button's too
Hope this help or can lead you to the solution you are looking

Categories

Resources