Android

【Android】expandable-recycler-viewを使ってみた。

今回使うのは、
thoughtbot/expandable-recycler-viewライブラリで
リストの折り畳みを行うものを作成してみました。
Gitはこちらです。
https://github.com/thoughtbot/expandable-recycler-view

Gradleでの読み込み

build.gradle

compile 'com.thoughtbot:expandablerecyclerview:1.3'

初期プロジェクトから作る人は、
compile ‘com.android.support:design:26.0.0-alpha1’も必要になります。

親子ビュークラスの作成

親ビュークラス

public class CustomParentViewHolder extends GroupViewHolder {
    private TextView parentTitleTextView;

    public CustomParentViewHolder(View itemView) {
        super(itemView);
        parentTitleTextView = itemView.findViewById(R.id.parent_title_text_view);
    }

    public void setTitle(ExpandableGroup group) {
        parentTitleTextView.setText(group.getTitle());
    }
}

子ビュークラス

public class CustomChildViewHolder extends ChildViewHolder {
    private TextView childNameTextView;

    public CustomChildViewHolder(View itemView) {
        super(itemView);
        childNameTextView = itemView.findViewById(R.id.child_name_text_view);
    }

    public void onBind(ChildItem childItem) {
        childNameTextView.setText(childItem.getName());
    }

    public void setName(String name) {
        childNameTextView.setText(name);
    }
}

レイアウトは省略します。

データ作成

全体のデータをまとめるクラスです。

public class Group extends ExpandableGroup<ChildItem> {
    public Group(String title, List items) {
        super(title, items);
    }
}

次に折り畳み表示させるデータクラスです。
Parcelableクラスは上記コードのExpandableGroupクラスでジェネリックで定義されているため必要になります。
ExpandableGroup<T extends Parcelable>

public class ChildItem implements Parcelable {

    private String name;

    public ChildItem(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    protected ChildItem(Parcel in) {
        this.name = in.readString();
    }

    public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
        public ChildItem createFromParcel(Parcel source) {
            return new ChildItem(source);
        }

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

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel parcel, int i) {
        parcel.writeString(name);
    }
}
Adapter
public class CustomExpandableViewAdapter extends ExpandableRecyclerViewAdapter<CustomParentViewHolder, CustomChildViewHolder> {

    private LayoutInflater  inflater;

    public CustomExpandableViewAdapter(List<? extends ExpandableGroup> groups, Context context) {
        super(groups);
        inflater = LayoutInflater.from(context);
    }

    @Override
    public CustomParentViewHolder onCreateGroupViewHolder(ViewGroup parent, int viewType) {
        View view = inflater.inflate(R.layout.parent_item_layout, parent, false);
        return new CustomParentViewHolder(view);
    }

    @Override
    public CustomChildViewHolder onCreateChildViewHolder(ViewGroup parent, int viewType) {
        View view = inflater.inflate(R.layout.child_item_layout, parent, false);
        return new CustomChildViewHolder(view);
    }

    @Override
    public void onBindChildViewHolder(CustomChildViewHolder holder, int flatPosition, ExpandableGroup group, int childIndex) {
        final ChildItem childItem = ((Group) group).getItems().get(childIndex);
        holder.setName(childItem.getName());
        Log.d("childItem.name", childItem.getName());
    }

    @Override
    public void onBindGroupViewHolder(CustomParentViewHolder holder, int flatPosition,
                                      ExpandableGroup group) {
        holder.setTitle(group);
    }
}
Activity
public class MainActivity extends AppCompatActivity {

    CustomExpandableViewAdapter adapter;

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

        List groups = getGroup();
        RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
        LinearLayoutManager layoutManager = new LinearLayoutManager(this);

        adapter = new CustomExpandableViewAdapter(groups, getApplicationContext());
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.setAdapter(adapter);
    }


    private List getGroup() {
        List rtnList = new ArrayList<>();
        List childItems = new ArrayList<>();
        ChildItem childItem = new ChildItem("にんじん");
        ChildItem childItem2 = new ChildItem("キャベツ");
        ChildItem childItem3 = new ChildItem("しいたけ");
        childItems.add(childItem);
        childItems.add(childItem2);
        childItems.add(childItem3);
        Group group = new Group("野菜", childItems);
        rtnList.add(group);

        List childItems2 = new ArrayList<>();
        ChildItem childItem2_1 = new ChildItem("バスケットボール");
        ChildItem childItem2_2 = new ChildItem("野球");
        ChildItem childItem2_3 = new ChildItem("サッカー");
        childItems2.add(childItem2_1);
        childItems2.add(childItem2_2);
        childItems2.add(childItem2_3);
        Group group2 = new Group("スポーツ", childItems2);
        rtnList.add(group2);

        return rtnList;
    }
}

完成したスクリーンショットです。

このようにきれいになったのですが、
後々テキストが崩れてきました。

なのでレイアウトがどうなってるか見てみました。

レイアウトで幅をmatch_parentにしているのにも関わらず、
幅が変わっていました。

まだ解決していないので、
解決方法が見つかれば紹介します。

追記:
私の場合TextViewの幅自体を固定値にすれば問題なく表示されました。
なぜか幅が変わっているようですね。

以上です。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です