AndroidのListView内でフォーカス可能なEditTextを実装する方法
はじめに
このチュートリアルでは、AndroidアプリのListView内にフォーカス可能なEditTextを作成する方法を解説します。リストの各行にEditTextを配置し、ユーザーが直接テキストを入力・編集できるようにするには、いくつかの重要な設定が必要です。以下の手順に沿って、サンプルコードとともに実装方法を見ていきましょう。
ステップ1:新規プロジェクトの作成
Android Studioを起動し、[File] → [New Project] を選択して新しいプロジェクトを作成します。必要な項目をすべて入力し、プロジェクトのセットアップを完了させてください。
ステップ2:activity_main.xmlの編集
res/layout/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="fill_parent"
android:layout_height="fill_parent"
android:descendantFocusability="beforeDescendants">
</ListView>
</LinearLayout>
ここで重要なのが android:descendantFocusability="beforeDescendants" の指定です。この属性により、ListView自身が子要素よりも先にフォーカスを処理できるようになり、EditTextへのフォーカス移動がスムーズになります。
ステップ3:リスト項目用レイアウトの作成
新しいレイアウトリソースファイル(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="fill_parent"
android:layout_height="wrap_content"
android:layout_marginStart="2dip"
android:singleLine="true">
</EditText>
</LinearLayout>
ステップ4:MainActivity.javaの実装
src/MainActivity.java に以下のコードを追加します。
import androidx.appcompat.app.AppCompatActivity;
import android.annotation.SuppressLint;
import android.app.LauncherActivity;
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;
ArrayList<LauncherActivity.ListItem> myItems = new ArrayList<>();
MyAdapter() {
layoutInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
for (int i = 0; i < 7; i++) {
LauncherActivity.ListItem listItem = new LauncherActivity.ListItem();
listItem.className = "Caption" + i;
myItems.add(listItem);
}
notifyDataSetChanged();
}
@Override
public int getCount() {
return myItems.size();
}
@Override
public Object getItem(int position) {
return 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, null);
holder.caption = convertView.findViewById(R.id.ItemCaption);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.caption.setText(myItems.get(position).className);
holder.caption.setId(position);
holder.caption.setOnFocusChangeListener(new View.OnFocusChangeListener() {
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus) {
final int position = v.getId();
final EditText Caption = (EditText) v;
myItems.get(position).className = Caption.getText().toString();
}
}
});
return convertView;
}
}
class ViewHolder {
EditText caption;
}
}
このコードのポイントは以下の通りです。
- setItemsCanFocus(true):ListViewの項目がフォーカスを受け取れるように設定します。この設定がないと、EditTextをタップしてもフォーカスが当たりません。
- ViewHolderパターン:convertViewを再利用してビューの参照を保持することで、スクロール時のパフォーマンスを向上させます。
- OnFocusChangeListener:フォーカスが外れたタイミングでEditTextの入力内容をデータソースに書き戻し、編集結果を保持します。
- setId(position):ビューのIDに行番号を持たせることで、どの項目が編集されたのかを特定できるようにしています。
ステップ5:AndroidManifest.xmlの編集
androidManifest.xml に以下のコードを追加します。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
package="app.com.sample">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<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>
</application>
</manifest>
android:windowSoftInputMode="adjustPan" を指定することで、ソフトキーボードが表示された際に画面全体が自動的に調整され、編集中のEditTextがキーボードに隠れないようになります。
アプリの実行
それでは、アプリケーションを実行してみましょう。ここでは、実際のAndroidスマートフォンをパソコンに接続しているものとします。
Android Studioからアプリを実行するには、プロジェクト内のアクティビティファイルを開き、ツールバーのRunアイコンをクリックします。実行デバイスとして自分のスマートフォンを選択してください。
アプリが起動すると、EditTextを含む7つのリスト項目が表示されます。各項目をタップするとフォーカスが当たり、テキストを自由に編集できます。別の項目へフォーカスが移動したタイミングで、それまでの入力内容がアダプター内のデータに保存される仕組みです。
-
【Android】EditTextにアルファベットのみ入力できるようにする方法
はじめにこの記事では、AndroidアプリのEditText(テキスト入力欄)に対して、アルファベットのみを入力可能にする方法を解説します。InputFilterと正規表現を組み合わせることで、数字や記号などの入力をブロックし、英字だけを受け付ける入力フィールドを簡単に実装できます。手順1:新規プロジェクトの作成まず、Android Studioで新しいプロジェクトを作成します。メニューから「File」→「New Project」を選択し、必要な項目を入力してプロジェクトを作成してください。手順2:レイアウトファイルの編集次に、res/layout/activity_main.xmlに以下のコ
-
【Android】ExpandableListViewでマルチレベル(階層型)リストを作成する方法
Androidアプリ開発では、カテゴリごとに項目を整理したマルチレベル(階層型)リストを実装したいケースが多くあります。本記事では、ExpandableListViewを使用して、親項目(グループ)をタップすると子項目が展開される2階層リストを作成する方法を、サンプルコードとともにステップごとに解説します。 ExpandableListViewとは? ExpandableListViewは、親項目(グループ)と子項目からなる2階層構造のリストを表示できるAndroid標準ウィジェットです。設定画面やFAQなど、階層的なデータをわかりやすく見せたい場面で活用できます。今回はスポーツ選手の一覧を例