AppCompatEditText is not shown - android

I have created a custom EditText to prevent pressing Enter (new line) in my input field. This is the class:
public class MyTextView extends android.support.v7.widget.AppCompatEditText {
public MyTextView(Context context) {
super(context);
}
public MyTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyTextView(Context context,
AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_ENTER) {
// Just ignore the [Enter] key
return true;
}
// Handle all other keys in the default way
return super.onKeyDown(keyCode, event);
}
}
First I extended the EditText class and it was working fine, but there was a warning to use AppCompatEditText instead (which extends EditText) . Now it doesn't appear. I've tried to enable, etc, but nothing seems to work. Anyone got an idea about this?
Bonus question: what about the Liskov substitution principle?
Thank you in advance.

Related

Customized Scrollable EditText in Scrollview Makes the Scrollview Jumps

I want to have a EditText in a scrollview and this EditText needs to be scrollable. So I made a customized one as follow:
public class myEditText extends EditText {
public myEditText(Context context) {
super(context);
}
public myEditText(Context context, AttributeSet attrs) {
super(context, attrs);
}
public myEditText(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#Override
public boolean onTouchEvent(MotionEvent ev) {
this.getParent().requestDisallowInterceptTouchEvent(true);
return super.onTouchEvent(ev);
}
}
This EditText has only one problem, that is when the text gets really long, the Scrollview containing it jumps for some reason. This makes me unable to edit text after a certain length. Is anyone know why that happens?
I think I solved it.
The issue was when there is a cursor in the EditText, the bringPointIntoView(int offset) method will make EditText scroll to the position where the cursor is at, so that the cursor will be in your sight and you can edit the text. Usually that's how it works, but when the EditText is in a ScrollView, instead of scroll the EditText, it makes the ScrollView scrolls as well. That's the reason I saw the ScrollView jumps.
The solution is simply override the bringPointIntoView method.
So if anyone wants to use a scrollable EditText in a ScrollView, I think this may help:
public class myEditText extends EditText {
public myEditText(Context context) {
super(context);
}
public myEditText(Context context, AttributeSet attrs) {
super(context, attrs);
}
public myEditText(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#Override
public boolean onTouchEvent(MotionEvent ev) {
this.getParent().requestDisallowInterceptTouchEvent(true);
return super.onTouchEvent(ev);
}
#Override
public boolean bringPointIntoView(int offset) {
return false;
}
}

Implement View.OnTouchListener on custom control

I created a view that extend RelativeLayout, and I what that, this view to be able to handle touch events. So what I thought about was to implement the OnTouchListener in my custom control, like this:
class MyCustomControl extends RelativeLayout implements View.OnTouchListener {
public MyCustomControl (Context context) {
super(context);
}
public MyCustomControl (Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyCustomControl (Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
other_methods;
#Override
public boolean onTouch(View view, MotionEvent event) {
//event handle here.
}
}
It doesn't work but if I do something like this, it does:
MyCustomControl control = (MyCustomControl) LayoutInflater.from(context).inflate(R.layout.my_control, null);
control.setOnTouchListener(control);
What should I do in order to have the touchListener built-in(already defined and activated) in my custom control ?
I know, it's late, but I solved my case by adding
this.setOnTouchListener(this);
to constructor

Make uneditable EditText respond to first click

I'm trying to make a popup menu appear when the user clicks on an EditText but I don't want the EditText itself to be editable. I've tried many things like setting its KeyListener to null, setting it's InputType to null, but what always happens is that the first click gives the View focus and the second click actually registers with my OnClickListener. So user has to click twice to get the menu to popup. Any ideas?
public class PopupEditText extends EditText implements OnClickListener
{
private PopupMenu mMenu;
private Context mContext;
public PopupEditText(Context context)
{
super(context);
init(context);
}
public PopupEditText(Context context, AttributeSet attrs)
{
super(context, attrs);
init(context);
}
public PopupEditText(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
init(context);
}
private void init(Context context)
{
mContext = context;
setKeyListener(null);
mMenu = new PopupMenu(context, this);
}
#Override
public void onClick(View view)
{
mMenu.show();
}
You're not far off. I'd recommend just overriding onTouchEvent() directly, and responding only to ACTION_UP events. Optionally, force it to be disabled and non-focusable. For example:
public class UnmodifiableEditText extends EditText {
private PopupMenu mPopupMenu;
public UnmodifiableEditText(Context context) {
super(context);
init(context);
}
public UnmodifiableEditText(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public UnmodifiableEditText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
private void init(Context ctx) {
super.setEnabled(false);
super.setFocusable(false);
mPopupMenu = new PopupMenu(ctx, this);
}
#Override public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
Toast.makeText(getContext(), "Showing Popup", Toast.LENGTH_SHORT).show();
mPopupMenu.show();
}
return true;
}
#Override public void setEnabled(boolean enabled) {
// Do not allow enabling the EditText
}
#Override public void setFocusable(boolean focusable) {
// Do not allow focusability changes
}
}

Advantage of Button over TextView with Selector

I was looking at the documentation for the Button widget and noticed that it is a subclass of TextView. Is there any real difference between a Button and a TextView if I use the same selector drawable on both. In other words, I already am using TextViews with selectors for my app's "buttons", but is there anything to be gained from using the Button class instead?
No, there's essentially no difference between TextView and Button. Button just comes styled as a button out of the box.
Here is the source for Button from API 19.
#RemoteView
public class Button extends TextView {
public Button(Context context) {
this(context, null);
}
public Button(Context context, AttributeSet attrs) {
this(context, attrs, com.android.internal.R.attr.buttonStyle);
}
public Button(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
super.onInitializeAccessibilityEvent(event);
event.setClassName(Button.class.getName());
}
#Override
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
super.onInitializeAccessibilityNodeInfo(info);
info.setClassName(Button.class.getName());
}
}

Android TimePicker (Wheel Style) not responding correctly to flick gestures inside ScrollView

I have a dialog box that contains a Scrollview, which contains a layout with two TimePickers.
The timepickers are the newer style ones, what's in ICS.
The problem is that they seem to fight for focus when you change the time by dragging the wheel, or flicking it. It will change the time just a little, and then the layout will scroll instead.
Any ideas?
Thanks in advance.
I had the same problem when using the Holo theme, and here is where I found the solution: https://groups.google.com/forum/?fromgroups#!topic/android-developers/FkSfJI6dH8w
You must implement your custom DatePicker or TimePicker and override the following method:
#Override
public boolean onInterceptTouchEvent(MotionEvent ev)
{
if (ev.getActionMasked() == MotionEvent.ACTION_DOWN)
{
ViewParent p = getParent();
if (p != null)
p.requestDisallowInterceptTouchEvent(true);
}
return false;
}
Because the link from Klemens Zleptnig is broken, here is a complete example. This fix helps with the scroll of a TabLayout too btw. I excluded the area around the big numbers in the top of the TimePicker because they don't need the scroll event anyway.
xml:
<com.name.app.MyTimePicker
android:id="#+id/timePicker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
.../>
java:
public class MyTimePicker extends TimePicker {
public MyTimePicker(Context context) {
super(context);
}
//This is the important constructor
public MyTimePicker(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyTimePicker(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public MyTimePicker(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
#Override
public boolean onInterceptTouchEvent(MotionEvent ev)
{
if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) {
//Excluding the top of the view
if(ev.getY() < getHeight()/3.3F)
return false;
ViewParent p = getParent();
if (p != null)
p.requestDisallowInterceptTouchEvent(true);
}
return false;
}
}

Categories

Resources