Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

List with Editable Textboxes in Android

DZone's Guide to

List with Editable Textboxes in Android

I am going to discuss how to create a List in Android having text label and associated edit box.

· Mobile Zone
Free Resource

In this article, I am going to discuss about creating a List in Android having text label and associated edit box. Here I am going to create a shopping list where user can enter the price for each item in the edit box.

We will see how to add edit box (EditText) into a list (ListView) and retrieve the values entered into the edit box. I had hard time in making the edit box remain focusable on first click. I will discuss the reason for this behavior and how to solve it towards the end of the article.

Creating a new project

Open Eclipse and create a new android project.


Choose a blank activity for the project.


Create main List layout

Open the layout file for the main activity and add a ListView component to it.
<ListView
            android:id="@+id/customlist"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_marginTop="5dp"/>

Create Custom layout for list items

The next step is to create a custom layout that will be used to represent each item in the list. Here we will define a custom layout using TextView and EditText android components.

Create a new layout file named listitems.xml and add TextView and EditText components to it as shown below:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal" >

<TextView
android:id="@+id/Item_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp" 
android:paddingTop="5dp"/>

<EditText
    android:id="@+id/Item_price"
    android:layout_width="80dp"
    android:layout_height="wrap_content"
    android:layout_alignParentRight = "true"
    android:layout_gravity="right"
    android:hint="Price"
    android:focusable="true"
    android:focusableInTouchMode="true"
    android:inputType="numberDecimal" />

</RelativeLayout>

Note here we have set the android:inputType  property of EditText  to “numberDecimal”. This will display numeric soft keyboard when focus is on the EditText. If you wish to input some other kind of data, you can set the android:inputType accordingly.

Create custom adapter

The next important step is to create a custom adapter which uses custom layout that we defined above, to add items to the list. The custom adapter should extend the ArrayAdapter. The getView() method of the adapter is invoked for each item of the list. In this method we assign shopping item names to TextView. Additionally onFocusChangeListener is added for the EditText. This is used to fetch the entered value in the edit box. The code for getView() looks like the following:

@Override
public View getView(int position, View view, ViewGroup parent) {
ListViewHolder viewHolder;
if (view == null) {
viewHolder = new ListViewHolder();
LayoutInflater inflater = context.getLayoutInflater();
view = inflater.inflate(R.layout.listitems, null, true);
viewHolder.itmName = (TextView) view.findViewById(R.id.Item_name);
viewHolder.itmPrice = (EditText) view.findViewById(R.id.Item_price);
view.setTag(viewHolder);
} else {
viewHolder = (ListViewHolder) view.getTag();
// loadSavedValues();
}

viewHolder.itmName.setText(itemNames[position]);
viewHolder.itmPrice.setId(position);
viewHolder.id = position;

if (selItems != null && selItems.get(position) != null) {
viewHolder.itmPrice.setText(selItems.get(position));
} else {
viewHolder.itmPrice.setText(null);
}

// Add listener for edit text
viewHolder.itmPrice
.setOnFocusChangeListener(new OnFocusChangeListener() {

@Override
public void onFocusChange(View v, boolean hasFocus) {
/*
 * When focus is lost save the entered value for
 * later use
 */

if (!hasFocus) {

int itemIndex = v.getId();

String enteredPrice = ((EditText) v).getText()
.toString();

selItems.put(itemIndex, enteredPrice);

}
}
});

return view;
}

Here we have created a Map to store item prices. This map is used to reload the input data when view got refreshed. These stored values could be further used in subsequent activities like calculating total amount spent on shopping etc.

Challenges and Solutions

1.  When you execute this application and click on any EditText in the list, numeric soft keyboard will be displayed. This action makes the list items render again. So the EditText that we clicked on gets rendered again and loses focus. The ListView gets the focus on this new list. To get the focus on the selected EditText we need to set the android:descendantFocusability property of parent ViewGroup which is ListView in our case. 

android:descendantFocusability="afterDescendants"

For more details on the android:descendantFocusability and other possible values, please refer to http://developer.android.com/reference/android/view/ViewGroup.html#attr_android:descendantFocusability

2. Another issue you will encounter is that if you select an EditText that is towards the end of the list, when the soft keyboard appears the EditText loses focus. This happens even if the ListView property mention in above point is set.  If you entered the number using keyboard this will get added to some random EditText. To solve this issue add the following for your activity in the app’s manifest file.

android:windowSoftInputMode="adjustPan"

References

Topics:
java ,mobile ,android ,listview ,editview ,editview focus soft keyboard

Published at DZone with permission of Davinder Singla. See the original article here.

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}