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

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

ただいまの
回答率

90.50%

  • Android

    7382questions

    Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Android listviewにSectionを追加したい

受付中

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 1,471
退会済みユーザー

退会済みユーザー

Android初心者です。

作成をしたlistviewについて、Sectionを追加したいと考え、こちらの記事を参考にさせていただきました。
ヘッダー行のみ表示したい場合どうすればよいのか教えていただきたいです。
よろしくお願い致します。
下部分に自分が行ったことを記述させていただきました。
http://dev.classmethod.jp/smartphone/android-listview-ios-uitableview/
ヘッダー行とデータ行について記載されていました。
こちらはSectionListFragment.javaの部分をActivityにすることで再現できたのですが、
自分の作った別のlistviewにヘッダー行だけを再現したいと思い、
BaseSectionAdapter.javaをまず引用させていただき

package jp.classmethod;

import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

public class BaseSectionAdapter<T1, T2> extends BaseAdapter {

  /** インデックス行:ヘッダー */
  private static final int INDEX_PATH_ROW_HEADER = -1;

  /** ビュータイプ:ヘッダー行 */
  private static final int ITEM_VIEW_TYPE_HEADER = 0;

  /** ビュータイプ:データ行 */
  private static final int ITEM_VIEW_TYPE_ROW = 1;

  protected Context context;
  protected LayoutInflater inflater;

  /** ヘッダー行で使用するデータリスト */
  protected List<T1> sectionList;

  /** データ行で使用するデータリスト */
  protected List<List<T2>> rowList;

  private List<IndexPath> indexPathList;

  public BaseSectionAdapter(Context context, List<T1> sectionList, List<List<T2>> rowList) {
    super();
    this.context = context;
    this.inflater = LayoutInflater.from(context);
    this.sectionList = sectionList;
    this.rowList = rowList;
    this.indexPathList = getIndexPathList(sectionList, rowList);
  }

  @Override
  public int getCount() {
    int count = indexPathList.size();
    return count;
  }

  @Override
  public Object getItem(int position) {
    IndexPath indexPath = indexPathList.get(position);
    if (isHeader(indexPath)) {
      return sectionList.get(indexPath.section);
    } else {
      return rowList.get(indexPath.section).get(indexPath.row);
    }
  }

  @Override
  public long getItemId(int position) {
    return position;
  }

  @Override
  public View getView(int position, View convertView, ViewGroup parent) {
    IndexPath indexPath = indexPathList.get(position);

    // ヘッダー行とデータ行とで分岐します。
    if (isHeader(indexPath)) {
      return viewForHeaderInSection(convertView, indexPath.section);
    } else {
      return cellForRowAtIndexPath(convertView, indexPath);
    }
  }

  /**
   * ヘッダー行のViewを返します。
   *
   * @param convertView
   * @param section
   * @return ヘッダー行のView
   */
  public View viewForHeaderInSection(View convertView, int section) {
    if (convertView == null) {
      convertView = inflater.inflate(android.R.layout.simple_list_item_1, null);
      TextView castedConvertView = (TextView) convertView;
      castedConvertView.setBackgroundColor(Color.GRAY);
      castedConvertView.setTextColor(Color.WHITE);
    }
    TextView textView = (TextView) convertView;
    textView.setText(sectionList.get(section).toString());
    return convertView;
  }

  /**
   * データ行のViewを返します。
   *
   * @param convertView
   * @param indexPath
   * @return データ行のView
   */
  public View cellForRowAtIndexPath(View convertView, IndexPath indexPath) {
    if (convertView == null) {
      convertView = inflater.inflate(android.R.layout.simple_list_item_1, null);
    }
    TextView textView = (TextView) convertView;
    textView.setText(rowList.get(indexPath.section).get(indexPath.row).toString());
    return convertView;
  }

  @Override
  public int getViewTypeCount() {
    // ヘッダー行とデータ行の2種類なので、2を返します。
    return 2;
  }

  @Override
  public int getItemViewType(int position) {
    // ビュータイプを返します。
    if (isHeader(position)) {
      return ITEM_VIEW_TYPE_HEADER;
    } else {
      return ITEM_VIEW_TYPE_ROW;
    }
  }

  @Override
  public boolean isEnabled(int position) {
    if (isHeader(position)) {
      // ヘッダー行の場合は、タップできないようにします。
      return false;
    } else {
      return super.isEnabled(position);
    }
  }

  /**
   * インデックスパスリストを取得します。
   *
   * @param sectionList
   * @param rowList
   * @return インデックスパスリスト
   */
  private List<IndexPath> getIndexPathList(List<T1> sectionList, List<List<T2>> rowList) {
    List<IndexPath> indexPathList = new ArrayList<IndexPath>();
    for (int i = 0; i < sectionList.size(); i++) {
      IndexPath sectionIndexPath = new IndexPath();
      sectionIndexPath.section = i;
      sectionIndexPath.row = INDEX_PATH_ROW_HEADER;
      indexPathList.add(sectionIndexPath);

      List<T2> rowListBySection = rowList.get(i);
      for (int j = 0; j < rowListBySection.size(); j++) {
        IndexPath rowIndexPath = new IndexPath();
        rowIndexPath.section = i;
        rowIndexPath.row = j;
        indexPathList.add(rowIndexPath);
      }
    }
    return indexPathList;
  }

  private boolean isHeader(int position) {
    IndexPath indexPath = indexPathList.get(position);
    return isHeader(indexPath);
  }

  private boolean isHeader(IndexPath indexPath) {
    if (INDEX_PATH_ROW_HEADER == indexPath.row) {
      return true;
    } else {
      return false;
    }
  }
}

このrowの部分を削除していきました。
 ヘッダー行とデータ行の2種類なので~のところはヘッダー行のみのため、
return 1;としました。
@Override 
  public Object getItem(int position) { 
    IndexPath indexPath = indexPathList.get(position); 
    if (isHeader(indexPath)) { 
      return sectionList.get(indexPath.section); 
    } else { 
      return rowList.get(indexPath.section).get(indexPath.row); 
    } 
  }
のelse~の部分をreturn indexpath;
とし、その他のelse分をreturnをそれぞれ入力し赤いエラーはなかったのですが、
実行をした際に、
null object referenceというエラーが出てしまいました。
上に記述したreturn indexpathのみは、return true; 等にしても
入力できた記憶があるのですが、
間違っている箇所はこちらであっているでしょうか。
また、もし完全に考え方が間違っており、違う場所の修正が必要な場合、教えていただきたいです。
長々と申し訳ございません。
よろしくお願い致します。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

0

ログキャットにnull object referenceが発生した行が書かれているはずです。その行は質問のコードのどこに当たるのでしょうか。
それがわかればなぜnullなのかを考える事で解決すると思いますよ。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

同じタグがついた質問を見る

  • Android

    7382questions

    Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。