質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.54%

リストビューのタイトルを真ん中にも入れたい

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 1,755

komon4242

score 11

いつもお世話になっています。
タイトルの内容で質問があります。

リストビューにタイトル(ヘッダ)をつけたいので以下の様なコードを書きました。

class MainActivity extends AppCompatActivity{

    private ListView listView;
    private CustomAdapter adapter;
    private List<String> list = new ArrayList<>();

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


        // 表示するListにデータを詰める
        for(int i=0; i < 100 ; i++){
            list.add("data "+ Integer.valueOf(i));
        }

        // Adapter - CustomAdapter::BaseAdapter
        adapter = new CustomAdapter(this, list);

        // ListViewに表示
        listView = (ListView) findViewById(R.id.list_item);     // Viewの紐づけ
        // タイトル(ヘッダ)をつける
        View titleView = View.inflate(this, R.layout.header_list, null);   // 第3引数は選択可否フラグ
        listView.addHeaderView(titleView, list, false);

        // カスタムリストをセットする
        listView.setAdapter(adapter);
    }
}

これで一応タイトルをつける事は出来ましたが、
例えば30行目と60行目と90行目にもタイトルをつけたいのですがどうやれば良いでしょうか?

ヒントだけでもお願いいたします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

check解決した方法

+1

翌日立って見直してみると、言わんとしている事は分かるが何を言いたいのかが分からないタイトルになってますね。
これでは回答はおろかViewも少ないわけだ。
グループごとのタイトルって言う名前が良かったですかね。

結論から言うと出来ました。
getView()の中で同じタイトルのリストが続く時はsetVisibility(View.GONE)を使って
詰めて非表示すれば、期待する表示になりますね。

こんな感じのクラスを作っておいて

class Data {
    String  Title;
    String  data;

    public Data(String title, String data){
        this.Title = title;
        this.data = data;
    }
}

MainActivityのListにデータを詰める所でこういう風に変更する。

private List<Data> list = new ArrayList<>();  // 定義はこういう風にする

// 表示するListにデータを詰める
for(int i=0; i < 100 ; i++){
    if((i%5)==0) {
        // タイトルの時はdataをnullにする
        list.add(new Data("Group " + Integer.valueOf(i/5+1), null));
    }
    // dataの時はタイトルをnullにする
    list.add(new Data(null, "data " + Integer.valueOf(i)));
}

getViewでタイトルの箇所だけ表示したい場合はこういう風にする

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

    ViewHolder holder;

    if (convertView == null) {   // 再利用できるViewがない

        convertView = inflate.inflate(R.layout.activity_item_view, parent, false);

        holder = new ViewHolder();
        holder.titleView = convertView.findViewById(R.id.groupTitle);
        holder.textView = convertView.findViewById(R.id.textview);

        // holderオブジェクトの保存
        convertView.setTag(holder);
    } else {
        // 再利用できるViewがある
        holder = (ViewHolder) convertView.getTag();
    }

    Data item = getItem(pos);

    if (item.Title != null ) {
    // タイトルがあるとき
        holder.titleView.setVisibility(View.VISIBLE);
        holder.titleView.setText(item.Title);
        holder.textView.setVisibility(View.GONE);
    } else {
    // dataがあるとき
        holder.titleView.setVisibility(View.GONE);
        holder.textView.setVisibility(View.VISIBLE);
        holder.textView.setText(item.data);
    }

    return convertView;
}

結果
リストビューにグループタイトルを

他に実装方法があればぜひ教えてください。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

ViewType を分けています.

まず共通の Item 型を定義し

abstract class Item {
    long _id;  //getItemId用
    ViewTypes viewType;  //getItemViewType用

    enum ViewTypes {
        TITLE, DATA
    }

    abstract View createView(LayoutInflater layoutInflater, ViewGroup parent);
    abstract void setValues(View convertView);
}


種類毎に継承してクラスを作ります. (以下はタイトルとデータの場合)

class TitleItem extends Item {
    private String title;
    TitleItem(String title) {
        viewType = ViewTypes.TITLE;  //'タイトル' タイプ
        this.title = title;
    }
    private class ViewHolder {  //TitleItem で必要な分
        TextView textView;
    }
    @Override
    View createView(LayoutInflater layoutInflater, ViewGroup parent) {
        ViewHolder vh = new ViewHolder();
        View view = layoutInflater.inflate(R.layout.list_title, parent, false);
        vh.textView = view.findViewById(R.id.list_title_textView);
        view.setTag(vh);
        return view;
    }
    @Override
    void setValues(View convertView) {
        ViewHolder vh = (ViewHolder) (convertView.getTag());
        vh.textView.setText(title);
    }
}
class DataItem extends Item {
    private String data1;
    private String data2;
    DataItem(String data1, String data2) {
        viewType = ViewTypes.DATA;  //'データ' タイプ
        this.data1 = data1;
        this.data2 = data2;
    }
    private class ViewHolder {  //DataItem で必要な分
        TextView textView1;
        TextView textView2;
    }
    @Override
    View createView(LayoutInflater layoutInflater, ViewGroup parent) {
        ViewHolder vh = new ViewHolder();
        View view = layoutInflater.inflate(R.layout.list_data, parent, false);
        vh.textView1 = view.findViewById(R.id.list_data_textView1);
        vh.textView2 = view.findViewById(R.id.list_data_textView2);
        view.setTag(vh);
        return view;
    }
    @Override
    void setValues(View convertView) {
        ViewHolder vh = (ViewHolder) (convertView.getTag());
        vh.textView1.setText(data1);
        vh.textView2.setText(data2);
    }
}


リストビュー用のアダプタはItemのリストを保持しておき、それにTitleItemやDataItemを入れておきます.

    private List<Item> list = new ArrayList<Item>();

    for(int i=0; i<100; i++) {
        if(i%5 == 0) {
            list.add(new TitleItem("group "+(i/5+1)));
        }
        list.add(new DataItem("data "+i, "test");
    }


また, ViewTypeに関するメソッドを2つOverwriteし, getViewでは各Itemのメソッドを呼びます.

    @Override
    public int getViewTypeCount() {
        return Item.ViewTypes.values().length; //Item.ViewTypesに定義された件数
    }
    @Override
    public int getItemViewType(int position) {
        return list.get(position).viewType.ordinal(); //enumで自動で付けられる番号
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        Item item = list.get(position);
        if(convertView == null) {
            convertView = item.createView(layoutInflater, parent);
        }
        item.setValues(convertView);
        return convertView;
    }

Item の種類がもっとあって, でも表示するレイアウトは使いまわせる場合等は, View 関係を Item から ViewTypes に移してもいいかもしれません.

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.54%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる