As Ofek stated in his answer the most appropriate way to do this is with recyclerView and a custom adapter.
First you need a layout for a single item in your list like this:
<?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="wrap_content"
android:orientation="horizontal">
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="60dp"
android:id="@+id/item_edittext"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/item_label"/>
</LinearLayout>
Next you have to create the adapter which handles the data and also listens for changes of text and focus:
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.CustomViewHolder> {
public static final String TAG = "CustomAdapter";
private List<String> labels;
public CustomAdapter(List<String> labels) {
this.labels = labels;
}
@Override
public int getItemCount() {
return labels.size();
}
@Override
public void onBindViewHolder(CustomViewHolder customViewHolder, int i) {
customViewHolder.label.setText(this.labels.get(i));
}
@Override
public CustomViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
//inflate layout and create new ViewHolder
View itemView = LayoutInflater.
from(viewGroup.getContext()).
inflate(R.layout.custom_item_layout, viewGroup, false);
return new CustomViewHolder(itemView);
}
//the viewHolder handles the single items in recylerview
public static class CustomViewHolder extends RecyclerView.ViewHolder {
protected TextView label;
protected EditText editText;
public CustomViewHolder(View v) {
super(v);
label = (TextView) v.findViewById(R.id.item_label);
editText = (EditText) v.findViewById(R.id.item_edittext);
//listen for changes in your editText
editText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
Log.d(TAG, s.toString());
}
@Override
public void afterTextChanged(Editable s) {
}
});
//listen for focusChangeEvents
editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
//at this point may save changed data
public void onFocusChange(View v, boolean hasFocus) {
if(! hasFocus) {
Log.d(TAG, getAdapterPosition()+" has lost focus ");
}
}
});
}
}
}
In your activity use it like this:
ArrayList<String> labels = new ArrayList<>();
labels.add("label1");
labels.add("label2");
labels.add("label3");
labels.add("label4");
labels.add("label5");
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerview);
CustomAdapter customAdapter = new CustomAdapter(labels);
recyclerView.setAdapter(customAdapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setHasFixedSize(true)