[AndroidStudio]fragmentにlistを表示する。テキストをリストに表示する方法。


目標

listviewで作ったfragmentにボタンを設置し、ボタンを押す、またはテキストを入力することでlistを作る。

完成画像は以下。

[button2][button3]をおすとそのままリストに表示。
[button1]を押すとtext内容をlistに表示。

コードは以下。

コード

[Item.java]
データを格納するため。

package com.example.ruihirano.myapplication3;

import android.os.Parcel;
import android.os.Parcelable;

public class Item implements Parcelable {
    public String id;
    public String name;

    public Item(String id, String name) {
        this.id = id;
        this.name = name;
    }

    public Item(Parcel in){
        this.id = in.readString();
        this.name = in.readString();
    }

    @Override
    public void writeToParcel(Parcel dest, int flags){
        dest.writeString(id);
        dest.writeString(name);
    }

    @Override
    public int describeContents() {
        return 0;
    }//FileDescriptor未使用の場合は0

    // 今は定型文という認識で
    public static final Creator<Item> CREATOR = new Creator<Item>() {
        public Item createFromParcel(Parcel in) {
            return new Item(in);
        }

        public Item[] newArray(int size) {
            return new Item[size];
        }
    };
}

[item_listfragment.xml]
fragmentのlayout。

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

    <LinearLayout
        android:id="@+id/linear_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <Button
            android:id="@+id/one"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="1" />

        <Button
            android:id="@+id/two"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="2" />

        <Button
            android:id="@+id/three"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="3" />

        <EditText
            android:id="@+id/edit"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_below="@+id/edit_tag"
            android:layout_centerHorizontal="true"
            android:hint="入力して下さい" />

    </LinearLayout>

    <ListView
        android:id="@id/android:list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:drawSelectorOnTop="false"/>

    //データがない場合に表示される
    <TextView
        android:id="@id/android:empty"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:text="No data"
        android:textSize="32sp"/>

</LinearLayout>

[custom_listview_item.xml]
リスト内のレイアウト。今回は左に数字、右にボタン、またはテキスト名を表示できるようにする。

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_margin="8dp"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/id"
        android:layout_width="wrap_content"
        android:layout_height="48dp"
        android:layout_weight="1"
        android:gravity="center"
        android:text="id"/>
    <TextView
        android:id="@+id/name"
        android:layout_width="wrap_content"
        android:layout_height="48dp"
        android:paddingLeft="16dp"
        android:layout_weight="4"
        android:gravity="center_vertical"
        android:text="name"/>

</LinearLayout>

[ItemListAdapter]
実際にリストを作る役割。
~~~
package com.example.ruihirano.myapplication3;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;

import java.util.ArrayList;

public class ItemListAdapter extends ArrayAdapter {

// 見易さのために定義。普段は直接 getView で指定する。
private static final int resource = R.layout.custom_listview_item;

public ItemListAdapter(Context context){
    super(context, 0);
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    // super.getView() は 呼ばない(カスタムビューにしているため)
    View view;

    // テンプレート処理。
    if (convertView == null) {
        LayoutInflater inflater = LayoutInflater.from(getContext());
        view = inflater.inflate(resource, parent, false);
    } else {
        view = convertView;
    }

    // データをgetItemで取る
    Item item = getItem(position);

    // カスタムビューの場合はViewが確実にあるtry-catch は不要ためか。
    TextView id = (TextView) view.findViewById(R.id.id);
    id.setText(item.id);
    TextView name = (TextView) view.findViewById(R.id.name);
    name.setText(item.name);

    return view;
}

// 設定されている CustomListItem の ArrayList を返す。
// 縦横切替などでデータを移行するために使う。
public ArrayList<Item> getItemList() {
    // 今回は Bundle#putParcelableArrayList() を使うことを想定する。
    // 必要に応じて Bundle#putSparseParcelableArray() を使ってもいい。

    int size = getCount();
    ArrayList<Item> itemList = new ArrayList<Item>(size);
    for (int index = 0; index < size; index++) {
        itemList.add(getItem(index));
    }
    return itemList;
}

// Bundleから復元するときに必要になるはず。
public void addAll(ArrayList<Item> parcelableArrayList) {
    // 強制でキャスト。落ちる場合は、設計か実装が間違っている。
    @SuppressWarnings("unchecked")
    ArrayList<Item> itemList = (ArrayList<Item>) parcelableArrayList;
    super.addAll(itemList);
}

public void add(String id, String name) {
    Item item = new Item(id, name);
    super.add(item);
}

// 削除
public void remove(int index) {
    if (index < 0 || index >= getCount()) {
        return;
    }
    remove(getItem(index));
}

}
~~~

[ItemListFragment.java]
ボタンがクリックされると、fragmentの情報をアダプターに渡す役割。

package com.example.ruihirano.myapplication3;

import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.LinearLayout;


public class ItemListFragment extends ListFragment {

    private ItemListAdapter adapter;

    public ItemListFragment() {
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //set adapter
        adapter = new ItemListAdapter(getActivity());
        setListAdapter(adapter);
    }

    @Override
    public void onStart() {
        super.onStart();

        this.getView().findViewById(R.id.one).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                EditText namae1 = (EditText)getView().findViewById(R.id.edit);
                String namae=namae1.getText().toString();
                adapter.add("1", namae);
            }
        });
        this.getView().findViewById(R.id.two).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                adapter.add("2", "button2");
            }
        });
        this.getView().findViewById(R.id.three).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                adapter.add("3", "button3");
            }
        });

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.item_listfragment, container, false);
    }

}

注意点(ハマったところ)

 this.getView().findViewById(R.id.one).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                EditText namae1 = (EditText)getView().findViewById(R.id.edit);
                String namae=namae1.getText().toString();
                adapter.add("1", namae);
            }
        });

onclickのあとにどのようにテキストを抽出するかでだいぶ時間がかかってしまった。

onclick内でfindviewidを使うには使いたいlayout(inflaterなどで)を取得してからview.findviewidと前につける。ここではgetview()でfragmentのレイアウトを取得している。

まとめ

以上のコードを用いることで実装ができた。