Salman Khan
Salman Khan

Reputation: 2832

Getting focus of EditText inside RecyclerView

I'm implementing an application in which user can store Debit Cards and later they can use it by just entering the CVV number of the same card. I have used RecyclerView for all the items(Debit Cards) stored by the user. Everything is working fine, view is rendering all good and I have used LinearLayoutManager to show Horizontal scroll.

Now the problem which I am facing is whenever I try to enter CVV of any card as soon as I click on it the view gets shifted towards the last item of the list of Stored Cards, So if I'm having three cards stored in my list and I try to enter CVV for the first one the view is shifting directly to the third card but the focus remains on the first cards EditText. I don't know what's going on with the same. I'm sharing some code part for the same.

Setting adapter and defining horizontal scroll :-

  recyclerAdapter = new RecyclerStoredCardAdapter(mContext, storedCards);
                LinearLayoutManager layoutManager
                        = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
                storedCardListRecycler.setLayoutManager(layoutManager);
                storedCardListRecycler.setVisibility(View.VISIBLE);
                storedCardListRecycler.setAdapter(recyclerAdapter);

Sharing the screenshots with this so it will get clear. Any help would be appreciable. Thanks.

enter image description here

Upvotes: 2

Views: 8889

Answers (2)

Roadblock
Roadblock

Reputation: 2071

Not able to reproduce this issue. Let me know if the following code does what you are facing. If not, can provide more feedback if you share you Adapter's Code.

MainActivity.java
public class MainActivity
  extends AppCompatActivity {

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

    RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
    MyAdapter adapter = new MyAdapter();
    recyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));
    recyclerView.setAdapter(adapter);
}
}


public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_ite, parent);
    return new MyViewHolder(view);
}

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
    ((EditText)((MyViewHolder)holder).mBinding.findViewById(R.id.editText)).setHint(position + " ");
}

@Override
public int getItemCount() {
    return 100;
}

public class MyViewHolder extends RecyclerView.ViewHolder {
    View mBinding;
    public MyViewHolder(View binding) {
        super(binding);
        this.mBinding = binding;
    }
}
}

The 2xml layouts:

<EditText
    android:id="@+id/editText"
    android:layout_height="200dp"
    android:layout_width="300dp"/>

</android.support.v7.widget.CardView>

My main_activity.xml is as follows:

<RelativeLayout
android:layout_height="match_parent"
android:layout_width="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android">

<android.support.v7.widget.RecyclerView
    android:id="@+id/recycler_view"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"/>
</RelativeLayout>

As you can see this is the simplest case. Let me know if I missed anything.

Upvotes: -1

Vishal Chhodwani
Vishal Chhodwani

Reputation: 2577

I have did this using ListView not with RecyclerView

But you can do with RecyclerView also.

Here is my used class demo.

SettingItemListViewAdapter.java


/**
 * Created by vishalchhodwani on 18/10/16.
 */
public class SettingItemListViewAdapter extends BaseAdapter {

    private final String TAG = "SettingItemListViewAdapter";

    Context context;
    List<SettingListViewItem> settingItemList;
    OnMyClickListeners onMyClickListeners;

    MyDatabaseAdapter myDatabaseAdapter;

    public SettingItemListViewAdapter(Context context, List<SettingListViewItem> settingItemList) {
        this.context = context;
        this.settingItemList = settingItemList;
        myDatabaseAdapter = new MyDatabaseAdapter(context);
    }

    public void setMyClickListener(OnMyClickListeners onMyClickListeners) {

        this.onMyClickListeners = onMyClickListeners;
    }

    @Override
    public int getCount() {
        return settingItemList.size();
    }

    @Override
    public Object getItem(int position) {
        return settingItemList.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {

        final ViewHolder holder;

        if (convertView == null) {
            holder = new ViewHolder();

            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = inflater.inflate(R.layout.setting_listview_item, parent, false);
            holder.settingListViewForm = (RelativeLayout) convertView.findViewById(R.id.settingListViewItem_form1);
            holder.vrijeTekst = (EditText) convertView.findViewById(R.id.settingListViewItem_ed_virje_row1);
            holder.kenteken = (EditText) convertView.findViewById(R.id.settingListViewItem_ed_kenketen_row1);

            holder.checkRow = (ImageView) convertView.findViewById(R.id.settingListViewItem_check_row1);
            holder.deleteRow = (ImageView) convertView.findViewById(R.id.settingListViewItem_deleteRow);

            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        holder.vrijeTekst.setText(settingItemList.get(position).getItemVrijeTekst());
        holder.kenteken.setText(settingItemList.get(position).getItemKenteken());


        boolean isSelected = settingItemList.get(position).isItemSelected();
        holder.checkRow.setImageResource(isSelected ? R.drawable.checked : R.drawable.uncheked);


        holder.vrijeTekst.setTag(position);
        holder.vrijeTekst.setOnFocusChangeListener(new View.OnFocusChangeListener() {
            public void onFocusChange(final View v, boolean hasFocus) {
                try {
                    if (!hasFocus) {
                        if (settingItemList.size() > 0) {
                            int position = (int) v.getTag();
                            EditText Caption = (EditText) v;
                            settingItemList.get(position).setItemVrijeTekst(Caption.getText().toString());
                        }

                    } else {
                        EditText caption = (EditText) v;
                        caption.setCursorVisible(true);

                    }
                } catch (Exception ex) {
                    ex.printStackTrace();
                }


            }
        });


        holder.kenteken.setTag(position);
        holder.kenteken.setOnFocusChangeListener(new View.OnFocusChangeListener() {
            public void onFocusChange(final View v, boolean hasFocus) {

                try {
                    if (!hasFocus) {
                        if (settingItemList.size() > 0) {
                            int position = (int) v.getTag();
                            EditText Caption = (EditText) v;
                            settingItemList.get(position).setItemKenteken(Caption.getText().toString());
                        }
                    } else {
                        EditText caption = (EditText) v;
                        caption.setCursorVisible(true);
                    }
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        });

        holder.checkRow.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                if (myDatabaseAdapter.isAvailableInTable(settingItemList.get(position).getItemId()))
                    onMyClickListeners.onSelectButtonClicked(position);
            }
        });

        holder.deleteRow.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                onMyClickListeners.onDeleteItemButtonClicked(position);
            }
        });


        if (getCount() == position + 1) {
            holder.vrijeTekst.requestFocus();
            holder.vrijeTekst.performClick();
        }

        return convertView;
    }

    public static class ViewHolder {
        RelativeLayout settingListViewForm;
        EditText vrijeTekst, kenteken;
        ImageView checkRow, deleteRow;
    }
}

SettingN_New.java (It is a fragment)


public class SettingN_New extends Fragment implements OnClickListener, OnMyClickListeners {

    private final String TAG = "SettingN_New";

    Context context;

    private TextView tv_demo;
    ToggleButton togglebtn_save;
    Button btn_save, btn_add;

    ListView settingItemListView;
    List<SettingListViewItem> settingItemList;
    SettingItemListViewAdapter settingItemListViewAdapter;

    MyDatabaseAdapter myDatabaseAdapter;

    TinyDB loginpref;

    boolean isNewRowAdded = true;


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        //This line of code will stay focus on selected edittext in list
        getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST);

        ActionBar bar = getActivity().getActionBar();
        bar.show();

        View rootView = inflater.inflate(R.layout.setting_new, container, false);

        initializeViews(rootView);

        setUI();

        getListOfItems();

        return rootView;
    }

    private void setUI() {

        try {
            if (loginpref.getBoolean(ConstantLib.PREF_AUTO_LOGIN)) {
                togglebtn_save.setChecked(true);
            } else {
                togglebtn_save.setChecked(false);
            }
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
    }

    private void initializeViews(View rootView) {
        context = getActivity();

        LayoutInflater inflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View headerView = inflater.inflate(R.layout.setting_listview_header, null);

        btn_save = (Button) headerView.findViewById(R.id.btn_save);
        btn_add = (Button) headerView.findViewById(R.id.btn_add);
        togglebtn_save = (ToggleButton) headerView.findViewById(R.id.togglebtn_save);
        tv_demo = (TextView) headerView.findViewById(R.id.tv_demo);

        settingItemList = new ArrayList<>();
        settingItemListView = (ListView) rootView.findViewById(R.id.setting_listView);
        settingItemListView.setClickable(true);
        settingItemListView.refreshDrawableState();
        settingItemListView.addHeaderView(headerView);
        settingItemListView.setItemsCanFocus(true);
        settingItemListViewAdapter = new SettingItemListViewAdapter(context, settingItemList);
        settingItemListViewAdapter.setMyClickListener(this);
        settingItemListView.setAdapter(settingItemListViewAdapter);


        myDatabaseAdapter = new MyDatabaseAdapter(context);
        loginpref = new TinyDB(getActivity());

        btn_save.setOnClickListener(this);
        btn_add.setOnClickListener(this);
        tv_demo.setOnClickListener(this);

        togglebtn_save.setOnCheckedChangeListener(new OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(CompoundButton buttonView,
                                         boolean isChecked) {
                // TODO Auto-generated method stub

                loginpref.putBoolean(ConstantLib.PREF_AUTO_LOGIN, isChecked);
            }
        });
    }


    private void getListOfItems() {

        settingItemList.clear();
        settingItemList.addAll(myDatabaseAdapter.getAllData());

        if (settingItemList.size() == 0) {
            isNewRowAdded = true;
            SettingListViewItem settingListViewItem = new SettingListViewItem();
            settingListViewItem.setItemId(settingItemList.size() + "");
            settingListViewItem.setItemVrijeTekst("");
            settingListViewItem.setItemKenteken("");
            settingListViewItem.setItemSelected(false);

            settingItemList.add(settingListViewItem);
        } else {
            isNewRowAdded = false;
        }
        notifyDataSetChanged();
    }

    private void hideKeyboard() {
        // Check if no view has focus:
        View view = getActivity().getCurrentFocus();
        if (view != null) {
            InputMethodManager inputManager = (InputMethodManager) getActivity()
                    .getSystemService(Context.INPUT_METHOD_SERVICE);
            inputManager.hideSoftInputFromWindow(view.getWindowToken(),
                    InputMethodManager.HIDE_NOT_ALWAYS);
        }
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_save:

                clearFocus();

                hideKeyboard();

                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {

                        if (isValidationSuccess())
                            saveAllData();
                    }
                }, 200);
                break;
            case R.id.btn_add:
                addAnotherRow();
                break;
            case R.id.tv_demo:
                clickedOnTvDemo();
                break;
        }
    }

    private void clickedOnTvDemo() {

        try {
            Intent i = new Intent(getActivity(), Setting_exp_activity.class);
            startActivity(i);

        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
    }

    private boolean isValidationSuccess() {
        Log.e(TAG, "isValidationSuccess() called : settingItemList.size()==" + settingItemList.size());

        for (int i = 0; i < settingItemList.size(); i++) {
            if (settingItemList.get(i).getItemVrijeTekst().equalsIgnoreCase("") || settingItemList.get(i).getItemKenteken().equalsIgnoreCase("")) {
                showToast("Veld mag niet leeg zijn");// showToast("Fields should not be empty!!");
                return false;
            }
        }

        return true;
    }

    private void saveAllData() {
        Log.e(TAG, "saveAllData() called");

        myDatabaseAdapter.clearTable();

        for (int i = 0; i < settingItemList.size(); i++) {
            isNewRowAdded = false;
            SettingListViewItem settingListViewItem = new SettingListViewItem();
            settingListViewItem.setItemId(i + "");
            settingListViewItem.setItemVrijeTekst(settingItemList.get(i).getItemVrijeTekst());
            settingListViewItem.setItemKenteken(settingItemList.get(i).getItemKenteken());
            settingListViewItem.setItemSelected(settingItemList.get(i).isItemSelected());

            myDatabaseAdapter.insertDataToTable(settingListViewItem);
        }

        DialogUtils.showInfoDialog(getActivity(),
                "Instellingen opgeslagen");
    }

    private void addAnotherRow() {
        Log.e(TAG, "addAnotherRow() called");
        if (settingItemList.size() > 0 && !isNewRowAdded) {
            if (!settingItemList.get(settingItemList.size() - 1).getItemVrijeTekst().equalsIgnoreCase("") && !settingItemList.get(settingItemList.size() - 1).getItemKenteken().equalsIgnoreCase("")) {
                isNewRowAdded = true;
                Log.e(TAG, "addAnotherRow() called check 1");

                SettingListViewItem settingListViewItem = new SettingListViewItem();
                settingListViewItem.setItemId(settingItemList.size() + "");
                settingListViewItem.setItemVrijeTekst("");
                settingListViewItem.setItemKenteken("");
                settingListViewItem.setItemSelected(false);
                settingItemList.add(settingListViewItem);

                notifyDataSetChanged();
            } else {
                Log.e(TAG, "addAnotherRow() called check 2");
                showToast("Al toegevoegd");// showToast("Already Added!!");
            }
        } else {
            if (!isNewRowAdded) {
                isNewRowAdded = true;
                Log.e(TAG, "addAnotherRow() called check 3");
                SettingListViewItem settingListViewItem = new SettingListViewItem();
                settingListViewItem.setItemId("0");
                settingListViewItem.setItemVrijeTekst("");
                settingListViewItem.setItemKenteken("");
                settingListViewItem.setItemSelected(false);
                settingItemList.add(settingListViewItem);

                notifyDataSetChanged();
            } else {
                Log.e(TAG, "addAnotherRow() called check 4");
                showToast("Al toegevoegd");// showToast("Already Added!!");
            }
        }

        settingItemListView.setSelection(settingItemList.size());

        Log.e(TAG, "addAnotherRow() called check 5");
        Log.e(TAG, "after settingItemList.size()==" + settingItemList.size());
    }

    @Override
    public void onDeleteItemButtonClicked(int position) {

        Log.e(TAG, "onDeleteItemButtonClicked() position==" + position);

        if (myDatabaseAdapter.getAllData().size() > 0)
            showAlertForDeleteItem(position);
        else
            showToast("Er is geen item te verwijderen"); //  showToast("No item to Delete");
    }

    @Override
    public void onSelectButtonClicked(int position) {
        Log.e(TAG, "onSelectButtonClicked() position==" + position);

        for (int i = 0; i < settingItemList.size(); i++) {
            Log.e(TAG, "onSelectButtonClicked() called check 3");
            settingItemList.get(i).setItemSelected(false);
        }

        settingItemList.get(position).setItemSelected(true);

        notifyDataSetChanged();
    }

    private void showAlertForDeleteItem(final int position) {
        AlertDialog.Builder alertDialog = new AlertDialog.Builder(context);
        alertDialog.setMessage("Weet je zeker dat je dit item wilt wissen?");//alertDialog.setMessage("Are you sure you want to delete this item?");

        // ja==yes
        alertDialog.setPositiveButton("Ja", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {

                myDatabaseAdapter.deleteTableRow(settingItemList.get(position).getItemId() + "");
                settingItemList.remove(position);
                settingItemListViewAdapter.notifyDataSetChanged();

                if (settingItemList.size() == position + 1) {
                    isNewRowAdded = false;
                }

                if (settingItemList.size() == 0) {
                    isNewRowAdded = false;
                    addAnotherRow();
                }
            }
        });

        //Annuleer==cancel
        alertDialog.setNegativeButton("Annuleer", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {


            }
        });

        alertDialog.show();
    }

    private void notifyDataSetChanged() {
        settingItemListViewAdapter.notifyDataSetChanged();
    }

    private void showToast(String message) {
        Toast.makeText(context, message, Toast.LENGTH_LONG).show();
    }

    public void clearFocus() {
        if (getActivity().getWindow().getCurrentFocus() != null) {
            getActivity().getWindow().getCurrentFocus().clearFocus();
        }
    }
}

I am giving you my whole class. why? Because it will give you more understanding that how I used it with ListView.

Test it and Let me know. :)

Note

  • This line of code is very important - getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST);

Upvotes: 3

Related Questions