কম্পিউটার টিউটোরিয়াল

অ্যান্ড্রয়েড ListView-এ ফোকাসযোগ্য EditText তৈরি করা

ListView-এ EditText ফোকাস সমস্যা সমাধান

ListView-এ EditText রাখলে ফোকাস সমস্যা হয় (কীবোর্ড আড়াল, স্ক্রলিং বাধা)। এই টিউটোরিয়ালটি দেখাবে `descendantFocusability` এবং কাস্টম অ্যাডাপ্টার ব্যবহার করে সমাধান করা।

পদক্ষেপ ১: প্রজেক্ট তৈরি করুন

Android Studio-তে নতুন প্রজেক্ট শুরু করুন।

পদক্ষেপ ২: মূল লেআউট (activity_main.xml)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="4dp"
    tools:context=".MainActivity">

    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:descendantFocusability="beforeDescendants" />

</LinearLayout>

পদক্ষেপ ৩: আইটেম লেআউট (listitem.xml)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <EditText
        android:id="@+id/ItemCaption"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="2dp"
        android:singleLine="true"
        android:hint="Enter text..." />

</LinearLayout>

পদক্ষেপ ৪: MainActivity.java - কাস্টম অ্যাডাপ্টার

import androidx.appcompat.app.AppCompatActivity;
import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.ListView;
import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {
    ListView listView;
    MyAdapter myAdapter;

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

        listView = findViewById(R.id.listView);
        listView.setItemsCanFocus(true); // গুরুত্বপূর্ণ!
        
        myAdapter = new MyAdapter();
        listView.setAdapter(myAdapter);
    }

    private class MyAdapter extends BaseAdapter {
        private LayoutInflater layoutInflater;
        private ArrayList items = new ArrayList<>();

        MyAdapter() {
            layoutInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            for (int i = 0; i < 7; i++) {
                items.add("Caption " + i);
            }
        }

        @Override public int getCount() { return items.size(); }
        @Override public Object getItem(int position) { return items.get(position); }
        @Override public long getItemId(int position) { return position; }

        @SuppressLint("InflateParams")
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder holder;
            
            if (convertView == null) {
                holder = new ViewHolder();
                convertView = layoutInflater.inflate(R.layout.listitem, parent, false);
                holder.caption = convertView.findViewById(R.id.ItemCaption);
                convertView.setTag(holder);
            } else {
                holder = (ViewHolder) convertView.getTag();
            }

            holder.caption.setText(items.get(position));
            holder.caption.setTag(position); // পজিশন সংরক্ষণ

            // ফোকাস চেঞ্জ লিসেনার - ডেটা আপডেট
            holder.caption.setOnFocusChangeListener((v, hasFocus) -> {
                if (!hasFocus) {
                    int pos = (int) v.getTag();
                    items.set(pos, ((EditText) v).getText().toString());
                }
            });

            return convertView;
        }
    }

    static class ViewHolder {
        EditText caption;
    }
}

পদক্ষেপ ৫: Manifest - সফট ইনপুট মোড

<activity android:name=".MainActivity" 
    android:windowSoftInputMode="adjustPan">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

মূল কী পয়েন্টসমূহ

  • android:descendantFocusability="beforeDescendants": ListView-কে ফোকাস হ্যান্ডলিং দেয়
  • listView.setItemsCanFocus(true): আইটেমগুলো ফোকাস পেতে পারে বলে বলে
  • windowSoftInputMode="adjustPan": কীবোর্ড আসলে লেআউট রিসাইজ না করে প্যান করে
  • ViewHolder প্যাটার্ন: পারফরম্যান্স এবং সঠিক ডেটা বাইন্ডিং নিশ্চিত করে

আধুনিক বিকল্প: RecyclerView

RecyclerView-এ এই সমস্যা কম, কিন্তু একই নীতি প্রয়োগ করুন। আরও ভালো: Jetpack Compose-এ TextField ব্যবহার করুন।

  1. অ্যান্ড্রয়েড ListView-এ ক্লিক ইভেন্ট হ্যান্ডল করার পদ্ধতি

  2. অ্যান্ড্রয়েডে রাউন্ডেড কর্নার সহ ListView তৈরি করার পদ্ধতি

  3. How to create editText accepts Alphabets only in Android?

  4. Android-এ মাল্টিলেভেল ListView (ExpandableListView) তৈরির পদ্ধতি