Blue note.

Android開発勉強ブログ。指摘ありましたらコメントください。

基本的なRecyclerViewを作る

Poplation Ranking

  • 人口ランキングをRecyclerViewで表示、チェックボックスで地域絞り込み
  • こんなものを作る
    f:id:mdvpo:20181118170258p:plain
    PoplationRanking

構成

  • MainActivity
  • RankAdapter : adpter
  • Data : データ配列を保持
  • activity_main
  • ranking_list : RecyclerView内部のView

実装方法

app > build.gradle

  • ライブラリを追加
  • dependencies {} implementation 'com.android.support:recyclerview-v7:28.0.0'

activity_main.xml

  • RecyclerViewを1つ用意
  <android.support.v7.widget.RecyclerView
      android:id="@+id/rankList"
      android:layout_width="match_parent"
      android:layout_height="wrap_content">
  </android.support.v7.widget.RecyclerView>

ranking_list.xml

  • RecyclerViewで使用する1列分のviewを作成
  • {順位、国名、人口数、地域}の4つを横並びで表示したいので以下のようにする。
  • 国ごとのテキストの長さにかかわらず4つの幅を固定させたいのでlayout_weightを使う
    • 順位1,国名4,人口2,地域2 でとりあえず割り振る
    • このときlayout_width="0dp"にしないとlayout_weightが効かない
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:padding="4dp">
    <TextView
        android:id="@+id/rank"
        android:layout_weight="1"
        android:layout_width="0sp"
        android:layout_height="wrap_content"
        android:textColor="#000000"/>
    <TextView
        android:id="@+id/country"
        android:layout_weight="4"
        android:layout_gravity="start"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:textColor="#000000"/>
    <TextView
        android:id="@+id/poplation"
        android:layout_weight="2"
        android:layout_gravity="start"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:textColor="#000000"/>
    <TextView
        android:id="@+id/area"
        android:layout_gravity="start"
        android:layout_weight="2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:textColor="#000000"/>
</LinearLayout>

参考 layout_weightの使い方 - ASとか

Data.java

  • 人口を載せてくれているサイトがあったのでそれを見て手打ちして文字列の二次元配列String[][]にする
  • 2/3が数値データなのにこのやり方ってどーなのと思いつつも最善策がわからずとりあえずこれで...
  • エリアの名前を毎回入力するのが手間なのでエリア配列areaArrayを作って番号を割り振る、data配列にはエリア名ではなくエリア番号を入力
  • エリア番号を確認しながら記入する作業面倒くさくて時間短縮できた気がしなかった

参考 世界の人口ランキング - 世界経済のネタ帳

public class Data {
    public static String[][]  data = {
            {"Chinese","1390","0" },
            {"India","1316","0" },
            ~~~省略~~
    };
}
    public static String[] areaArray ={
      "アジア","北米","中南米","ヨーロッパ","オセアニア","中東","アフリカ"
    };

RankAdapter.java

  • RecyclerViewにセットするためのAdapterを用意
  • ざっとこんな感じ
public class RankAdapter extends RecyclerView.Adapter<RankAdapter.ViewHolder> {

    String[][] array;
    
    class ViewHolder extends RecyclerView.ViewHolder{
        TextView rank;
        TextView country;
        TextView poplation;
        TextView area;

        ViewHolder(View view){
            super(view);
            rank = view.findViewById(R.id.rank);
            country = view.findViewById(R.id.country);
            poplation = view.findViewById(R.id.poplation);
            area = view.findViewById(R.id.area);
        }
    }
    RankAdapter(String[][] _array){
        array = _array;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        LayoutInflater layoutInflater = LayoutInflater.from(viewGroup.getContext());
        View view = layoutInflater.inflate(R.layout.ranking_list, viewGroup, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder viewHolder, int i) {
        viewHolder.rank.setText("No."+ String.valueOf(i+1));
        viewHolder.country.setText(array[i][0]);
        viewHolder.poplation.setText(array[i][1]);
        viewHolder.area.setText(Data.areaArray[Integer.parseInt(array[i][2])]);
    }

    @Override
    public int getItemCount() {
        return array.length;
    }
}
  • ViewHolder
    • リスト一行ごとにfindViewByIdしてたら重くなるけどviewHolderで指定しておけば1回で済んで高速化できる、という代物らしい
    • データを渡すview(今回はすべてTextView)の指定を行っておく

参考

ViewHolderを使わないでListViewを高速化する - Qiita Android ListViewとAdapterとViewHolder - うちなー えんじにあ ぶろぐ

  • onCreateViewHolder
    • Layoutの設定
  • onBindViewHolder

    • 各viewにデータをセット
  • getItemCount

    • ここの戻り値分onCreateViewHolderonBindViewHolderが処理される
    • 最初、処理ちゃんと描いたのに何も表示されない!なんで!とおもったらここがreturn 0;になってた...
    • とりあえずデータを全部突っ込んどいても、条件でデータ数変えられるのは地味に便利そう

ListView,ArrayAdapter

基本的なListView

  • MainActivityにListViewを用意
  • 別にlayoutを作り、そこにTextViewを用意
  • ※TextViewがリストのそれぞれのアイテムの見た目になり、それをListViewが並べるのでリストの行幅や色はTextViewで、リスト全体のサイズ等はListViewで定義
  • 配列を作成
  • ArrayAdapterを作成。
    • ArrayAdapter (Context context, int resource, T[] objects)
    • ArrayAdapter(context, TextViewを含むlayout, 配列) ※違うパターンの引数も有
public class MainActivity extends AppCompatActivity {

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

        ListView listView = findViewById(R.id.list_item);

        String[] member = {"debbie","lou","tammy","nineball","amita","constance","rose","daphne"};
        ArrayAdapter<String> arrayAdapter = new ArrayAdapter<>(getApplicationContext(),R.layout.list,member);
        listView.setAdapter(arrayAdapter);

    }
}

f:id:mdvpo:20181007171928p:plain

ボタンタップで文字の色を変える

hahahaはじめまして。 とりあえずブログ書きます。勉強ブログなので「ここ違うよ!」「こういう書き方のがイケてるよ」というご意見等ありましたらぜひコメントください。誹謗中傷はお断り。

つくったもの

f:id:mdvpo:20180902170655p:plain

ボタンをタップすると"Hello World!"の文字がその色に変化するというもの。画像はREDボタンをタップした状態。

書いたコード

package,impor文は省きます。それ以外はベタ貼り。

public class MainActivity extends AppCompatActivity {

    public TextView text;

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

        Button red = findViewById(R.id.redButton);
        Button green = (Button) findViewById(R.id.greenButton);
        Button blue = findViewById(R.id.blueButton);
        text = findViewById(R.id.textView);

        red.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                text.setTextColor(Color.RED);
            }
        });
        green.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                text.setTextColor(Color.GREEN);
            }
        });
        blue.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                text.setTextColor(Color.BLUE);
            }
        });
    }
}

学び

  • clickイベントの実装
オブジェクト.setOnClickListener(new View.OnClickListener() {
    @Override
            public void onClick(View view) {
// 処理
            }
}
  • findViewById(R.id.redButton).setOnClickListener() でもいけるけど最初にボタン定義しといたほうがわかりやすいのでまとめた

詰まったとこ

  • ボタン定義をsetContentViewする前に書いちゃってアプリ起動即停止 → 定義する場所とかprivate,publicなどそこらへんまだまだよくわかってない

ばかまるだしっ!なブログ一発目ですが更新していくことで開発者としての腕を磨く一つの要因になればいいなと思ってます。

おしまい。