Hot questions for Using Android EditText in xml

Question:

I have a standard straight forward EditText, I want to show the dictionary suggestions on top of this EditText so I did this in the XML:

<EditText
 android:id="@+id/messaging_messageEdit"
 android:layout_width="0dp"
 android:layout_height="wrap_content"
 android:layout_gravity="center"
 android:layout_margin="10dp"
 android:layout_weight="85"
 android:background="@drawable/clanz_edit_text_holo_dark"
 android:ems="10"
 android:hint="Type your message here..."
 android:singleLine="true"
 android:inputType="textAutoComplete"
 android:textColor="#dedede" >
</EditText>

I thought that the inputType parameter would take care of the auto dictionary view. On my phone (Nexus Android 5.1) the dictionary view appears but is blank. On a Genymotion emulator (Android 4.1.1) it does not display at all.

What am I missing?


Answer:

This can be one solutions if you are looking for AutoComplete TextView.

<AutoCompleteTextView
                    android:id="@+id/from_station"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:hint="@string/enter_start"
                    android:imeOptions="actionNext"
                    android:inputType="textNoSuggestions"
                    android:textColorHint="@color/transparent_black" />

You can also set threshold value using paramters. Need to set adapter values at runtime.

Question:

This is a problem I've been experiencing for quite some time and have already reached out about — other Android programmers found it intriguing.

Context: I have a custom EditText view that relies on XML for instantiation. I have two methods to create this view: either it is within the Layout file of the current Activity (1) or I dynamically add it to the layout at runtime using an Inflater (2). With both methods, the object is defined exactly the same in XML. However, there is a behavior with one that doesn't show in the other.

Behaviors: When using the first method, I get the correct and expected behavior, which is the following: The user types in the center of the EditText (restricted to one horizontal line). Once the user has typed enough to exceed the bounds of the EditText, the EditText will wrap_content to accommodate. When it changes width, the change is anchored to the middle of the view. Length is thus added to both the right AND the left of the box. When using the second method, I get the incorrect behavior: the width change is anchored to the left! Length is added to the right only.

Issue: I'd like to see the correct behavior with the second method and understand why the behavior could be different even though the XML is the same.

What I've Done: I've already reached out for help on the Android Studio Discord and have tried to tweak different aspects of the shared XML. The last thing I've done is to verify this problem still occurs with regular EditText and that my custom class isn't to blame.

Code Snippets: the shared XML (in activity layout OR "tag.xml")

<com.lab.guy.opener.TagView
    xmlns:app="http://schemas.android.com/apk/res-auto"

    style="@style/TagStyle"

    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintRight_toRightOf="parent" />

And "TagStyle":

 <style name="TagStyle">
    <item name="android:textSize">14sp</item>
    <item name="android:layout_height">21sp</item>
    <item name="android:layout_width">wrap_content</item>
    <item name="android:gravity">center</item>

    <item name="android:paddingLeft">10dp</item>
    <item name="android:paddingRight">10dp</item>

    <item name="android:focusableInTouchMode">true</item>
    <item name="android:maxLines">1</item>
    <item name="android:lines">1</item>
    <item name="android:singleLine">true</item>
    <item name="android:maxLength">20</item>
    <item name="android:inputType">textNoSuggestions|textVisiblePassword</item>
    <item name="android:imeOptions">actionDone</item>

    <item name="android:hint">@string/tag</item>
    <item name="android:textColor">@color/tag</item>
    <item name="android:textCursorDrawable">@drawable/tag_cursor</item>
    <item name="android:background">@drawable/tag_background</item>
</style>

The main layout is a ConstraintLayout.

If you need any other resources for testing, please do tell!

The only code I'm not willing to share is from TagView.java, since the problem occurs with standard EditTexts too.

Thank you very much from reading this far!

Edit: I've tried out more things to do, such as cross-testing on other devices and trying out other layout types (under Linear or Relative, I get the incorrect behavior regardless of which method I use). Currently, I'm trying to recreate the correct behavior on a default EditText that uses the second instantiation method (this time, trying out different XML).


Answer:

I have found a non-satisfactory workaround which nullifies the problem, and I'll share it for anyone who might experience this in the future. The initial question, however, remains unanswered.

So: if ever you need to instantiate a text-centered content-wrapping EditText through an Inflater and do not want width to be added to the right only, you must create a custom EditText child class equipped with a TextWatcher.

protected static int widthDiffThreshold = 4; //todo: verify

protected String rem;
protected String add;
protected int remLength;
protected int addLength;
protected Rect remBounds = new Rect();
protected Rect addBounds = new Rect();
protected Rect curBounds = new Rect();


private class SimpleTextListener implements TextWatcher{
    @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        getPaint().getTextBounds(s.toString(), 0, s.length(), curBounds);

        if(((getWidth() - getResources().getDimension(R.dimen.myPadding)*2) - curBounds.width()) <= widthDiffThreshold){
            rem = s.subSequence(start, start + count).toString();
        } else rem = null;
    }
    @Override public void onTextChanged(CharSequence s, int start, int before, int count) {
        if(rem!=null) {
            add = s.subSequence(start, start + count).toString();

            getPaint().getTextBounds(rem, 0, rem.length(), remBounds);
            getPaint().getTextBounds(add, 0, add.length(), addBounds);

            remLength = -remBounds.width(); //todo: simplify
            addLength = addBounds.width();

            setX(getX() - ((float)remLength + (float)addLength) /2);
        }
    }

    @Override
    public void afterTextChanged(Editable s) {
        //some code
    }
}

What this code is effectively doing is the following: whenever the text is changed, we first check if the width difference between the text content and the containing box is low enough to warrant an automatic width-change (handled via the wrap-content attribute). To know this, I've measured a somewhat approximate threshold, but I invite you to do your own research to verify this value is appropriate.

If your view has padding, you should also take it into account here.

If a width-change will indeed occur, we now store the string that is going to be modified as well as the the string which will replace the first. This method ensures that selecting&copy-pasting does not break the system. In normal typing, the "rem" string will be empty when adding a letter and the "add" string will be empty when removing one.

Now, we measure both of those strings in real units, subtract the removed length from the added and move the view by half of the total. I've kept some variables which can be removed for clarity.

This, thankfully, seems to work very well. Some adjustments might be necessary and I'll update this answer whenever I discover any bugs.

Good luck out there!

Question:

I don't want the user to insert anything in the middle of the EditText box. I only want to allow the user to click on the EditText box to bring out the keyboard, and insert at the end of the EditText box.

Is there a way to disable the ability for the user to change the cursor position when clicking on the EditText box?

I don't mind if the answer if done in XML or Java.

Thank you :)

Edit: if I have to use setSelection, is there a way to detect when the EditText box is clicked? so that I can set the cursor back to the end when the user click on the EditText.


Answer:

Use setSelection to set the cursor position. But that won't lock the insertion point. You can tell if someone changes the selection if you create a custom view and subclass EditText to override setSelectionChanged to force a different change to your liking. You may also want to override onTextChanged to verify that any change that happens does not break your rules.

Question:

I have an error with Google's Login template. I use the login activity, but I always get the following error in the rendering/design screen:

The following classes could not be found:
- EditText (Fix Build Path)
Tip: Try to build the project.

The problem is caused by the android:imeActionId xml-methods. Here is my (Google's) code:

<EditText
                android:id="@+id/password"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="@string/prompt_password"
                android:imeActionId="@+id/login"
                android:imeActionLabel="@string/action_sign_in_short"
                android:imeOptions="actionUnspecified"
                android:inputType="textPassword"
                android:maxLines="1"
                android:singleLine="true" />

If I remove all android:ime[...] lines, its rendering perfectly fine. I use Android Studio 1.5.1 and compileSdkVersion 21

I hope you can help me to fix this issue!

Cheers!


Answer:

This is due to misleading name of android:imeActionId line.

It's initial value "@+id/login" indicates it's setting its own id value, but instead it's expecting you to assign one.

Please look at Why does setting imeActionId with a predefined ID resource create an error?

It provides a solution that worked for me.

Question:

I created a custom EditText so as to be able to move and resize the EditText. It is working on my phone but crashed on other phone when i start to type.

When i added android:inputType="text" to the Xml Code it worked but the whole purpose of the application was lost Here is the full stack error

java.lang.IndexOutOfBoundsException
   at android.graphics.Paint.getTextRunAdvances(Paint.java:1841)
   at android.graphics.Paint.getTextRunAdvances(Paint.java:1818)
   at android.text.TextLine.handleText(TextLine.java:755)
   at android.text.TextLine.handleRun(TextLine.java:907)
   at android.text.TextLine.measureRun(TextLine.java:414)
   at android.text.TextLine.measure(TextLine.java:293)
   at android.text.TextLine.metrics(TextLine.java:267)
   at android.text.Layout.getLineExtent(Layout.java:977)
   at android.text.Layout.drawText(Layout.java:329)
   at android.widget.Editor.drawHardwareAccelerated(Editor.java:1384)
   at android.widget.Editor.onDraw(Editor.java:1298)
   at android.widget.TextView.onDraw(TextView.java:5061)
   at com.oluwayomi.quotage.custom.DragEditText.onDraw(DragEditText.java:340)
   at android.view.View.draw(View.java:13917)
   at android.view.View.getDisplayList(View.java:12832)
   at android.view.View.getDisplayList(View.java:12876)
   at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3019)
   at android.view.View.getDisplayList(View.java:12755)
   at android.view.View.getDisplayList(View.java:12876)
   at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3019)
   at android.view.View.getDisplayList(View.java:12755)
   at android.view.View.getDisplayList(View.java:12876)
   at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3019)
   at android.view.View.getDisplayList(View.java:12755)
   at android.view.View.getDisplayList(View.java:12876)
   at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3019)
   at android.view.View.getDisplayList(View.java:12755)
   at android.view.View.getDisplayList(View.java:12876)
   at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3019)
   at android.view.View.getDisplayList(View.java:12755)
   at android.view.View.getDisplayList(View.java:12876)
   at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3019)
   at android.view.View.getDisplayList(View.java:12755)
   at android.view.View.getDisplayList(View.java:12876)
   at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3019)
   at android.view.View.getDisplayList(View.java:12755)
   at android.view.View.getDisplayList(View.java:12876)
   at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3019)
   at android.view.View.getDisplayList(View.java:12755)
   at android.view.View.getDisplayList(View.java:12876)
   at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3019)
   at android.view.View.getDisplayList(View.java:12755)
   at android.view.View.getDisplayList(View.java:12876)
   at android.view.HardwareRenderer$GlRenderer.draw(HardwareRenderer.java:1249)
   at android.view.ViewRootImpl.draw(ViewRootImpl.java:2520)
   at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2387)
   at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2189)
   at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1181)
   at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4942)
   at android.view.Choreographer$CallbackRecord.run(Choreographer.java:776)
   at android.view.Choreographer.doCallbacks(Choreographer.java:579)
   at android.view.Choreographer.doFrame(Choreographer.java:548)
   at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:762)
   at android.os.Handler.handleCallback(Handler.java:800)
   at android.os.Handler.dispatchMessage(Handler.java:100)
   at android.os.Looper.loop(Looper.java:194)
   at android.app.ActivityThread.main(ActivityThread.java:5370)
   at java.lang.reflect.Method.invokeNative(Native Method)
   at java.lang.reflect.Method.invoke(Method.java:525)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
   at dalvik.system.NativeStart.main(Native Method)

Here is the XML Code

<RelativeLayout
            android:id="@+id/TextRoot"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <com.oluwayomi.quotage.custom.DragEditText
                android:id="@+id/etText"
                style="@style/Widget.AppCompat.Button.Borderless"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerHorizontal="true"
                android:layout_gravity="center"
                android:layout_marginTop="124dp"
                android:background="@drawable/null_background"
                android:gravity="center"
                android:padding="10dp"
                android:hint="Type text here.\n Double tap to edit \n and long press to resize."
                android:textSize="22sp" />
        </RelativeLayout>

Here is the code for my custom EditText

    public DragEditText(Context context) {
        this(context, null);

    }

    public DragEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
        mPaintFrame = new Paint();
        mPaintTranslucent = new Paint();
        c = context;

        RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        this.setLayoutParams(layoutParams);
    }

    public DragEditText(Context context, AttributeSet attrs, int defStyleAttr) {
        this(context, attrs);

    }  @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int viewWidth = MeasureSpec.getSize(widthMeasureSpec);
        int viewHeight = MeasureSpec.getSize(heightMeasureSpec);

        mParentWidth = c.getResources().getDisplayMetrics().widthPixels;
        mParentHeight = c.getResources().getDisplayMetrics().heightPixels;
        mParentRect = new RectF(0, 0, viewWidth, viewHeight);
    }
@Override
    protected void onDraw(Canvas canvas) {
        drawDragFrame(canvas);
        super.onDraw(canvas);
    }
     private void drawDragFrame(Canvas canvas) {
            if (showResizeFrame) {
                drawFrame(canvas);
                drawHandleShadows(canvas);
                drawHandles(canvas);
            } else if (showDragFrame) {
                drawHighlight(canvas);
            }
        }

        private void drawFrame(Canvas canvas) {
            mPaintFrame.setAntiAlias(true);
            mPaintFrame.setFilterBitmap(true);
            mPaintFrame.setStyle(Paint.Style.STROKE);
            mPaintFrame.setColor(getResources().getColor(R.color.colorAccent));
            mPaintFrame.setStrokeWidth(1);
            canvas.drawRect(mFrameRect.left + mHandleSize / 2, mFrameRect.top, mFrameRect.right - mHandleSize / 2, mFrameRect.bottom, mPaintFrame);
        }

        private void drawHighlight(Canvas canvas) {
            mPaintTranslucent.setAntiAlias(true);
            mPaintTranslucent.setFilterBitmap(true);
            mPaintTranslucent.setStyle(Paint.Style.FILL);
            mPaintTranslucent.setColor(TRANSLUCENT_WHITE);
            mPaintTranslucent.setStrokeWidth(1);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                canvas.drawRoundRect(mFrameRect.left, mFrameRect.top, mFrameRect.right - mHandleSize, mFrameRect.bottom, mHandleSize, mHandleSize, mPaintTranslucent);
            } else
                canvas.drawRect(mFrameRect.left, mFrameRect.top, mFrameRect.right - mHandleSize, mFrameRect.bottom, mPaintTranslucent);
        }

        private void drawHandles(Canvas canvas) {
            //drawHandleShadows(canvas);
            mPaintFrame.setStyle(Paint.Style.FILL_AND_STROKE);
            mPaintFrame.setColor(getResources().getColor(R.color.colorAccent));


            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                canvas.drawRoundRect(mFrameRect.left, mFrameRect.top + mHandleSize, mFrameRect.left + mHandleSize, mFrameRect.bottom - mHandleSize, mHandleSize / 2, mHandleSize / 2, mPaintFrame);
                canvas.drawRoundRect(mFrameRect.right - mHandleSize, mFrameRect.top + mHandleSize, mFrameRect.right, mFrameRect.bottom - mHandleSize, mHandleSize / 2, mHandleSize / 2, mPaintFrame);
            } else {
                canvas.drawRect(mFrameRect.left, mFrameRect.top + mHandleSize, mFrameRect.left + mHandleSize, mFrameRect.bottom - mHandleSize, mPaintFrame);
                canvas.drawRect(mFrameRect.right - mHandleSize, mFrameRect.top + mHandleSize, mFrameRect.right, mFrameRect.bottom - mHandleSize, mPaintFrame);
            }

        }

        private void drawHandleShadows(Canvas canvas) {
            mPaintFrame.setStyle(Paint.Style.FILL);
            mPaintFrame.setColor(TRANSLUCENT_BLACK);
            RectF rect = new RectF(mFrameRect);
            rect.offset(0, 1);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                canvas.drawRoundRect(rect.left, rect.top + mHandleSize, rect.left + mHandleSize, rect.bottom - mHandleSize, mHandleSize / 2, mHandleSize / 2, mPaintFrame);
                canvas.drawRoundRect(rect.right - mHandleSize, rect.top + mHandleSize, rect.right, rect.bottom - mHandleSize, mHandleSize / 2, mHandleSize / 2, mPaintFrame);
            } else {
                canvas.drawRect(rect.left, rect.top + mHandleSize, rect.left + mHandleSize, rect.bottom - mHandleSize, mPaintFrame);
                canvas.drawRect(rect.right - mHandleSize, rect.top + mHandleSize, rect.right, rect.bottom - mHandleSize, mPaintFrame);
            }
    }

Answer:

After searching without seeing a helpful solution, I finally discovered the problem

style="@style/Widget.AppCompat.Button.Borderless"

Cannot be applied EditText.

Thanks to everyone.

Question:

In my application I have edit texts, which must ignore spacebar every time the user enters it. I've written the next in my XML for edit texts in order for this to work:

android:digits="АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдеёжзийклмнопрстуфхцчшщъыьэюя"
android:inputType="textFilter"

So logically, it must only accept uppercase and lowercase russian letters, but when I double tap on spacebar, the letter in edit text is removed, as if I tapped backspace button. Why is this happening and what is the solution for it?


Answer:

Something is missing in here, it doesn't make sense for spacebar to remove letter on double or single tap. There must be something with your keyboard you are using in Android or must have written something more than above-given code for the implementation, which might be causing some issue.

Question:

In the code below, when the 'submit' button is pushed, I'm trying to get the values from three editTexts. After I get the String values, I want to convert them to int values and check whether they are in the specified range.

However I am having trouble getting the values from editText. I'm not sure if this is the problem or if there is another even bigger flaw with my code.

When I enter the three editTexts and press the 'submit' button, the app stops with the 'submit' button pressed down. It seems as if it's in some sort of loop - just a guess. So, the toast msg doesn't appear on my screen(Even after I changed my code with what @sunnyday mentioned). The app just seems stalled. It won't even go back to the previous activity.

I am just starting Android and any suggestions would be greatly appreciated.

Java Code:

package activities;

import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;

import com.example.chloe.myapplication.R;

public class PayActivity extends ActionBarActivity implements View.OnClickListener {
    Button submitButton, flip;
    Switch switchButton;
    EditText et_totalPeople, et_payPeople, et_amount;
    TextView tv_payPeople, tv_people;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.pay_numofpeople);

        submitButton = (Button) findViewById(R.id.submitButton);
        switchButton = (Switch)findViewById(R.id.switchButton);
        et_totalPeople= (EditText) findViewById(R.id.et_totalPeople);
        et_payPeople= (EditText) findViewById(R.id.et_payPeople);
        et_amount = (EditText) findViewById(R.id.et_amount);

        switchButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if(isChecked == true) {
                    et_payPeople.setEnabled(false);
                    et_payPeople.setClickable(false);
                } else {
                    et_payPeople.setEnabled(true);
                    et_payPeople.setClickable(true);
                }
            }
        });
        submitButton.setOnClickListener(this);
    }
    public void onClick(View v) {
        switch(v.getId()){
            case R.id.submitButton:
                int people = Integer.parseInt(et_totalPeople.getText().toString());
                //tested with toast here.. didn't work, which means it can't even read from editText
                Toast.makeText(getApplicationContext(), people, Toast.LENGTH_LONG).show();
                while(people<1 || people>100) {
                    Toast.makeText(getApplicationContext(), "Enter values 1~100", Toast.LENGTH_LONG).show();
                    et_totalPeople.setSelectAllOnFocus(true);
                    people = Integer.parseInt(et_totalPeople.getText().toString());
                }
                if(switchButton.isChecked()==false) { /*Only certain people pay*/
                    int payer = Integer.parseInt(et_payPeople.getText().toString());
                    while(payer<1 || payer>100) {
                        Toast.makeText(getApplicationContext(), "Enter values 1~100", Toast.LENGTH_LONG).show();
                        et_payPeople.setSelectAllOnFocus(true);
                        payer = Integer.parseInt(et_payPeople.getText().toString());
                    }
                }
                int amount = Integer.parseInt(et_amount.getText().toString());
                while(amount<1 || amount>10000000) {
                    Toast.makeText(getApplicationContext(), "Enter values 1~10,000,000", Toast.LENGTH_LONG).show();
                    et_amount.setSelectAllOnFocus(true);
                    amount = Integer.parseInt(et_amount.getText().toString());
                }
                /*now all three values are valid, continue*/
            break;
        }
    }
}

xml code:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/restaurant2_lighter"
    android:layout_gravity="center">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginRight="10dp"
        android:layout_marginLeft="10dp"
        android:layout_gravity="center"
        android:orientation="vertical">
        <View
            android:layout_width="fill_parent"
            android:layout_height="1dp"
            android:background="#6effc118"/>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="10dp">
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:text="Everyone pays:   "
                android:textSize="15dp"
                android:textColor="#ffffff"/>
                <Switch
                    android:id="@+id/switchButton"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textOff="NO"
                    android:textOn="YES"
                    android:textSize="15dp"/>
            </LinearLayout>
        <View
            android:layout_width="fill_parent"
            android:layout_height="1dp"
            android:background="#6effc118"/>
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="10dp">
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Enter\nthe number\nof people"
                android:textSize="15dp"
                android:textColor="#ffffffff"
                android:layout_marginRight="40dp"/>
            <EditText
                android:id="@+id/et_totalPeople"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:hint="ex) 1~99  "
                android:layout_gravity="center"
                android:background="#4be3cc86"
                android:textColor="#ffffffff"
                android:padding="10dp"
                android:inputType="numberDecimal" />
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text=" people"
                android:textColor="#ffffffff"
                android:layout_gravity="center"/>
            </LinearLayout>
        <View
            android:layout_width="fill_parent"
            android:layout_height="1dp"
            android:background="#6effc118"/>
            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:padding="10dp">
                <TextView
                    android:id="@+id/tv_payPeople"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Enter\nthe number\nof people\nto pay"
                    android:textColor="#ffffffff"
                    android:layout_marginRight="40dp"
                    android:textSize="15dp"/>
                <EditText
                    android:id="@+id/et_payPeople"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:hint="ex) 1~99  "
                    android:layout_gravity="center"
                    android:background="#4be3cc86"
                    android:textColor="#ffffffff"
                    android:padding="10dp"
                    android:inputType="numberDecimal" />
                <TextView
                    android:id="@+id/tv_people"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text=" people"
                    android:textColor="#ffffffff"
                    android:layout_gravity="center"/>
                </LinearLayout>
        <View
            android:layout_width="fill_parent"
            android:layout_height="1dp"
            android:background="#6effc118"/>
            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:padding="10dp">
                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Enter\nthe total\namount"
                    android:textSize="15dp"
                    android:textColor="#ffffffff"
                    android:layout_marginRight="40dp"/>
                <EditText
                    android:id="@+id/et_amount"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:hint="ex) 50000  "
                    android:layout_gravity="center"
                    android:background="#4be3cc86"
                    android:textColor="#ffffffff"
                    android:padding="10dp"
                    android:inputType="numberDecimal" />
                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text=" won"
                    android:textColor="#ffffffff"
                    android:layout_gravity="center"/>
                </LinearLayout>
        <View
            android:layout_width="fill_parent"
            android:layout_height="1dp"
            android:background="#6effc118"/>
            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center">
                <Button
                    android:id="@+id/submitButton"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="submit"
                    android:padding="10dp"
                    android:textSize="20dp"
                    android:layout_marginTop="30dp"/>
                </LinearLayout>
        </LinearLayout>
</LinearLayout>

Thank you for your time :)


Answer:

You get stuck in an endless loop in your validations as soon as a wrong value is entered. Lets say I enter 101 for people then you end up in this loop as soon as you hit the submit button.

while(people<1 || people>100) {
    Toast.makeText(getApplicationContext(), "Enter values 1~100",   Toast.LENGTH_LONG).show();
    et_totalPeople.setSelectAllOnFocus(true);
    people = Integer.parseInt(et_totalPeople.getText().toString());
}

The reason is, that your while loop runs in the UI thread of your app and therefore you cannot enter a different value, because for that to be possible the edit text field would need the UI thread for itself.

To solve this, do something like this (in pseudo code):

onclick() {
    if (people < 1 || people > 100) {
        showToast();
        return;
    }
    if (other-validation-condition == false) {
        showOtherToast();
        return;
    }
    if (yet-another-validation-condition == false) {
        showYetAnotherToast();
        return;
    }
    // now, everything should be valid...
    continueDoingStuffWithValidatedValues();
}

Question:

Sorry for my English. I am using the library MaskedEditText. Everything works fine, but I can get text(only text). Example: I have XML:

<br.com.sapereaude.maskedEditText.MaskedEditText 
    android:id="@+id/phoneNumber"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginLeft="3dp"
    android:background="@null"
    android:inputType="number"
    mask:mask="(###) ###-##-##"
>
</br.com.sapereaude.maskedEditText.MaskedEditText>

If the user enters text: (111) 111-11-11, I should get only 1111111111.

Below is my code

MaskedEditText text = (MaskedEditText) findViewById(R.id.phoneNumber);
Toast.makeText(MainActivity.this, "Text without mask: " +
    text.getText(true), Toast.LENGTH_LONG).show();

The error: The method getText() in the type EditText is not applicable for the arguments (boolean)

UPDATE If i use these methods:

Log.e("Mask ", text.getMask());
Log.e("getCharRepresentation ",
    String.valueOf(text.getCharRepresentation()));
Log.e("getCharRepresentation ", text.getText().toString());

Its output:

05-30 12:41:40.448: E/Mask(7980): (###) ###-##-##
05-30 12:41:40.448: E/getCharRepresentation(7980): #
05-30 12:41:40.448: E/getCharRepresentation(7980): (111) 111-11-11

Answer:

Okay, assuming that you only have (, ), and - that you wish to remove..

String str = String.valueOf(text.getCharRepresentation());
str = str.replaceAll("\\D", ""); // Replace all non-digits

Here is an example:

public class TestReplacement {

    public static void main (String [] args) {

        String str = "(111) 111-11-11";

        System.out.println("String before replacement: " + str);

        str = str.replaceAll("\\D", ""); // Replace all non-digits

        System.out.println("String after replacement: " + str);
    }
}

Output:

String before replacement: (111) 111-11-11
String after replacement: 1111111111

Question:

My EditText has a background that makes it round and with a stroke of 3dp, I am trying to have a permanent indent implemented so that the text doesn't start in the stroke of the background. All ive come across is android: paddingStart/paddingEnd and I can not seem to get it to work. Is there any other way of achieving this programmatically or no? I would want it about 1dp past the stroke or maybe 3dp but I can't find a way to achieve this.

xml

<EditText android:id="@+id/w_SearchBarFullScreen"
      xmlns:android="http://schemas.android.com/apk/res/android" 
      android:layout_width="355dp"
      android:layout_height="40dp"
      android:layout_marginBottom="8dp"
      android:layout_marginTop="8dp"
      android:background="@drawable/web_search_bar"
      android:imeOptions="actionSearch"
      android:inputType="text"
      android:maxLines="1"
      android:singleLine="true"
      android:text="    "
      android:elevation="5dp"
      android:focusable="true"/>

background xml

<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#fff" />

<stroke
    android:width="3dp"
    android:color="#e0e0e0" />
<corners
    android:radius="15dp"/>

<padding
    android:left="0dp"
    android:top="0dp"
    android:right="0dp"
    android:bottom="0dp" />
</shape>

Answer:

Remove padding from background.xml

use paddingLeft="10dp"

in Edittext

Question:

I need to implement an EditText which allows text more than the screen size as in:

android:inputType="textLongMessage"

But also supports the Enter key as in:

android:inputType="textMultiLine"

Tried overriding dispatchKeyEvent but still unable to fix this.

<EditText
        android:id="@+id/basicBatEdittext"
        android:layout_width="fill_parent"
        android:layout_height="0dp"
        android:layout_weight="3"
        android:background="#000"
        android:gravity="top"
        android:scrollHorizontally="true"
        android:hint="Hey there!\nHow is it going?"
        android:inputType="textLongMessage"
        android:padding="6dp"
        android:textColor="#fff"
        android:textColorHint="#fff"
        android:textCursorDrawable="@null" />


    @Override
public boolean dispatchKeyEvent(KeyEvent event) {

    if (event.getKeyCode() == KeyEvent.KEYCODE_ENTER || event.getKeyCode() == KeyEvent.ACTION_DOWN || event.getKeyCode() == KeyEvent.KEYCODE_NAVIGATE_NEXT) {

        String temp = edittext.getText().toString() + "\n";
        edittext.setText(temp);

            return true;
        }

    return super.dispatchKeyEvent(event);
};

It just appends two blank spaces to the EditText.


Answer:

textLongMessage is a text variation (corresponding to TYPE_CLASS_TEXT | TYPE_TEXT_VARIATION_LONG_MESSAGE), while textMultiLine is a flag (TYPE_TEXT_FLAG_MULTI_LINE), so you can theoretically mix them :

  android:inputType="textMultiLine|textLongMessage"

I don't know why but it only works if you also set scrollHorizontally to true programatically

someEditText.setHorizontallyScrolling(true);

Question:

I'm using a GridLayout in my activity and I used a couple EditText to fill the grid. The width and everything looked good. Now I want to add the EditTexts dynamic to the existing GridLayout. But I have some problems to translate the XML attributes to Java. Especially I don't know how to set the columnWeight correct.

This is the GridLayout:

<GridLayout
                android:id="@+id/cellGrid"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:columnCount="8"
                android:rowCount="5">
...
</GridLayout>

This was one of the correct looking XML EditTexts:

<EditText
                    android:layout_width="20dp"
                    android:layout_height="wrap_content"
                    android:layout_columnWeight="1"
                    android:layout_marginBottom="2dp"
                    android:layout_marginEnd="2dp"
                    android:background="@color/middelGrey"
                    android:inputType="numberDecimal"
                    android:textAlignment="center"
                    android:textSize="12dp" />

And this is how I try to add the EditTexts to the Grid in a for-loop

for(int i=0; i < amountOfCells/2; i++){
        EditText editText = new EditText(getContext());

     editText.setBackgroundColor(getResources().getColor(R.color.middelGrey, null));
        editText.setInputType(InputType.TYPE_NUMBER_FLAG_DECIMAL);

        LinearLayout.LayoutParams llp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT, 1f);
        llp.setMargins(0, 0, 2, 2);
        editText.setLayoutParams(llp);
        editText.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
        editText.setWidth(20);
        editText.setHeight(wrap_content);
        gridLayout.addView(editText, i);
    }

But it doesn't look like the xml version, I think the columnWeight is not set correct.


Answer:

Set following layout parameters instead of yours:

GridLayout.LayoutParams parem = new LayoutParams(GridLayout.spec(GridLayout.UNDEFINED, 1f),  GridLayout.spec(GridLayout.UNDEFINED, 1f));

This can be found here: Link

Question:

I have a EditText view :

  <EditText
            android:id="@+id/vorgabezeit"
            android:layout_width="50dp"
            android:layout_height="wrap_content"
            android:background="#0277BD"
            android:imeOptions="actionDone"
            android:inputType="numberDecimal"
            android:maxLength="5"
            android:textAlignment="textEnd"
            android:textColor="#ffffff"
            android:textCursorDrawable="@null"
            android:textStyle="bold"
            />

The value entered in this EditText I would like to use it in an math operation. Before I had fixed values :

public void submitOrder(View view) {
     displayPrice((procente / myEditNum) * mitarbeiter);
}

where variables were defined as :

int procente = 120;
int mitarbeiter = 1;

Now, I searched for hours on the web how to take that value entered in EditText and use id further, and this is as close as I got :

public class MainActivity extends AppCompatActivity {
    int procente = 120;
    int mitarbeiter = 1;
    EditText myEdit = (EditText) findViewById(R.id.vorgabezeit);
    String myEditValue = myEdit.getText().toString();
    double myEditNum = Double.parseDouble(myEditValue);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    public void submitOrder(View view) {
        displayPrice((procente / myEditNum) * mitarbeiter);
    }
}

The application crashes from the start. Thank you for your patience and help.

Best regards, Robert


Answer:

First you need to post the LogCat when you are having a crash.

Second You can not call findViewById until after setContentView is called. You should to initialize your edit text in onCreate.

// Initialize values in onCreate after setContentView
EditText myEdit;
String myEditValue;
double myEditNum;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    myEdit = (EditText) findViewById(R.id.vorgabezeit);
    myEditValue = myEdit.getText().toString();
    myEditNum = Double.parseDouble(myEditValue);
}

Question:

So I am creating headers and input fields programmatically in a loop. As it stands with the following code, all the elements appear bunched together on top of one another:

    RelativeLayout mRlayout = (RelativeLayout) findViewById(R.id.checkFieldsLayout);
    RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
            RelativeLayout.LayoutParams.MATCH_PARENT,
            RelativeLayout.LayoutParams.WRAP_CONTENT);
    params.addRule(RelativeLayout.ALIGN_PARENT_TOP); 
    Bundle extras = getIntent().getExtras();
    List<String> fields = extras.getStringArrayList("checkList");

    for (int i = 0; i < fields.size(); i++) {
        TextView header = new TextView(this); // Pass it an Activity or Context
        header.setText(fields.get(i).toString());
        header.setLayoutParams(params);
        EditText field = new EditText(this);
        field.setLayoutParams(params);
        mRlayout.addView(header);
        mRlayout.addView(field);
    }   

How do I programmatically lay out these elements so they match the width of the screen and dock one beneath the other? Thank you!


Answer:

Try This:

RelativeLayout mRlayout = (RelativeLayout) findViewById(R.id.checkFieldsLayout);
Bundle extras = getIntent().getExtras();
List<String> fields = extras.getStringArrayList("checkList");

RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
     RelativeLayout.LayoutParams.MATCH_PARENT,
     RelativeLayout.LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.ALIGN_PARENT_TOP); 


TextView header1 = new TextView(this); // Pass it an Activity or Context
header.setText(fields.get(0).toString());
header.setLayoutParams(params);
header1.setId(0);

RelativeLayout.LayoutParams params2 = new RelativeLayout.LayoutParams(
     RelativeLayout.LayoutParams.MATCH_PARENT,
     RelativeLayout.LayoutParams.WRAP_CONTENT);
params2.addRule(RelativeLayout.BELOW,0);

EditText field1 = new EditText(this);
field.setLayoutParams(params2);
field1.setId(fields.size());

mRlayout.addView(header);
mRlayout.addView(field);

for (int i = 1; i < fields.size(); i++) {
    RelativeLayout.LayoutParams params1 = new RelativeLayout.LayoutParams(
         RelativeLayout.LayoutParams.MATCH_PARENT,
         RelativeLayout.LayoutParams.WRAP_CONTENT);
    params2.addRule(RelativeLayout.BELOW,fields.size()+i -1);

    TextView header = new TextView(this); // Pass it an Activity or Context
    header.setText(fields.get(i).toString());
    header.setId(i);
    header.setLayoutParams(params1);

    RelativeLayout.LayoutParams params2 = new RelativeLayout.LayoutParams(
         RelativeLayout.LayoutParams.MATCH_PARENT,
         RelativeLayout.LayoutParams.WRAP_CONTENT);
    params2.addRule(RelativeLayout.BELOW, i);

    EditText field = new EditText(this);
    field.setLayoutParams(params2);
    field.setId(fields.size()+i);

    mRlayout.addView(header);
    mRlayout.addView(field);
}  

Question:

I am making a Assignment don't know how to add a multilines edittext follow this one Tutorial but don't know how to implement it in MainActivity class

Drawing multiple lines in edittext e.g. notepad

i am using following class

public class LinedEditText extends EditText {

    private Rect mRect;
    private Paint mPaint;

    // we need this constructor for LayoutInflater
    public LinedEditText(Context context, AttributeSet attrs) {
        super(context, attrs);

        mRect = new Rect();
        mPaint = new Paint();
        mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
      //  mPaint.setColor(getResources().getColor()); //SET YOUR OWN COLOR HERE
    }

    @Override
    protected void onDraw(Canvas canvas) {
        //int count = getLineCount();

        int height = getHeight();
        int line_height = getLineHeight();

        int count = height / line_height;

        if (getLineCount() > count)
            count = getLineCount();//for long text with scrolling

        Rect r = mRect;
        Paint paint = mPaint;
        int baseline = getLineBounds(0, r);//first line

        for (int i = 0; i < count; i++) {

            canvas.drawLine(r.left, baseline + 1, r.right, baseline + 1, paint);
            baseline += getLineHeight();//next line
        }

        super.onDraw(canvas);
    }

}

and i have following xml view wanted to inflat them via this class

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:id="@+id/main_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

</LinearLayout>

multilinedittext.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/multiline_exdittext_layout"
    android:layout_width="match_parent" android:layout_height="match_parent">

    <EditText
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:inputType="textMultiLine"
        android:ems="10"
        android:id="@+id/edittxt_multilines"
        />

</LinearLayout>

Answer:

Whats your mistake

Your custom class is public class LinedEditText extends EditText

  1. Did you call this in your XML

Just Change your EditText Xml

    <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/multiline_exdittext_layout"
    android:layout_width="match_parent" android:layout_height="match_parent">

    <YOUR_PACKAGE_NAME.LinedEditText
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:inputType="textMultiLine"
        android:ems="10"
        android:id="@+id/edittxt_multilines"
        />

</LinearLayout>

Question:

I have an XML that has an edit text on it, a java file connected to it that can receive the edit text and turn into a string no problem

XML

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="10dp"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context="com.coopery.notes.NoteActivity"
android:background="#da141415">

<EditText
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/etTitle"
    android:layout_alignParentStart="true"
    android:inputType="textCapSentences|textAutoCorrect"
    android:imeOptions="actionDone"
    android:hint="Title..."
    android:textSize="17sp"
    android:textColor="#ffffffff" />

<EditText
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:inputType="textMultiLine|textCapSentences|textAutoCorrect"
    android:scrollbars="vertical"
    android:ems="10"
    android:id="@+id/etNote"
    android:layout_below="@id/etTitle"
    android:layout_alignParentStart="true"
    android:gravity="top"
    android:background="@null"
    android:hint="Note..."
    android:textSize="17sp"
    android:textColor="#ffffffff" />

Java

public class NoteActivity extends Activity {

Typeface customFont;

EditText etTitle;
EditText etNote;

String oldTitle;
AlarmPage A = new AlarmPage();
Notification.Builder notification;
NotificationManager manager;
private String Title, Note1, Note;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_note);



    String fileName = getIntent().getStringExtra(MainActivity.EXTRA_TITLE);
    oldTitle = fileName;

    etTitle = (EditText) findViewById(R.id.etTitle);
    etNote = (EditText) findViewById(R.id.etNote);

    String Title = etTitle.getText().toString();
    String Note = etNote.getText().toString();

but another java file when I try to get the same code, it get's a null. How could I do it?

If I'm not specific enough, please let me know, it's a bit of a hard question to ask. Here's the method from the other java file which I am trying to use and receive the edittext

 public void notification() {
    setContentView(R.layout.activity_note);
    EditText TitleE, NoteE;

    TitleE = (EditText) findViewById(R.id.etTitle);
    NoteE = (EditText)findViewById(R.id.etNote);

    String Title, Note;

    Title = TitleE.getText().toString();
    Note = NoteE.getText().toString();


    //both PingService and CommonConstants java files are needed for this method


    NotificationCompat.Builder notification = new NotificationCompat.Builder(this)
            .setSmallIcon(R.drawable.ic_launcher)
            .setContentTitle(Title)
            .setContentText(Note)
            .setDefaults(Notification.DEFAULT_ALL) // requires VIBRATE 
            .setStyle(new NotificationCompat.BigTextStyle().bigText("hi"));

Note: I put a second setContentView to see if it worked, it didn't.


Answer:

Modify enTitle and enNote declaration like this, this will make them global across all your activities:

public static EditText etTitle;
public static EditText etNote;

Then you'll be able to get their values from other activities, however if you try to change them from other activities, you'll get an exception.

If someone else will modify your code, it's better to make these variables private, and create two methods instead:

public static String getTitle() {
    return enTitle.getText().toString();
};
public static String getNote() {
    return enNote.getText().toString();
};