CSVファイルを読み込んでリスト表示 – Android Studio

参考サイト:https://qiita.com/mii-chang/items/94fad3a778377a18ccf5

プロジェクト名:CSVReadSample

自分専用の時刻表を作成するつもりで始めたが、データベースを使う方が楽かも。

CSVで作ったリストを表示する。
作成したcsvファイルは「drowable」内にtest.csvというファイルをインストールするので削除しない限り、再起動しても、別のディバイスにインストールしても消えることは無い。編集の修正があれば「drowable」内csvファイルを直接編集することも出来るし、インストールし直す事もできる。

CSVのコンマ区切りで数が少ないとアプリが落ちる。読み込みの数よりCSVファイルが多い分は問題ないが少ないと問題が出てくるので注意!

CSVのファイル読み込みはファイル内の「, 」区切りが増えたりすると後で面倒な追加作業が色々と出てくるのでパターンが固定された状態で扱える場合は便利な方法ではある。

内容が変化する場合はSQLite等のデータベースを使った方が最終的には楽になるとうことかもしれない。

assetsディレクトリの作成

app -> Folder -> Assets Folderでassetsディレクトリを作成し、作成したCSVファイルのアイコンを右クリックしてコピー、Assetsを選択して「貼り付け」ファイルパスのダイアログが出るのでOK、これでcsvファイルが入る。

かなり省略してcsvファイルを作っている。テキストにコンマ区切りで作成して、最後に.csvと入れるだけ。
そのファイルをコピーしてassetsディレクトリにに貼り付けするとインストールが完了する。

AM 06,52,柚木(矢峰経由),35,矢峰,45,矢峰行き,52,矢峰
AM 06,52,柚木(矢峰経由),35,矢峰,45,矢峰行き,52,矢峰
AM 06,52,柚木(矢峰経由),35,矢峰,45,矢峰行き,52,矢峰
AM 06,52,柚木(矢峰経由),35,矢峰,45,矢峰行き,52,矢峰
AM 06,52,柚木(矢峰経由),35,矢峰,45,矢峰行き,52,矢峰
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <ListView
        android:id="@+id/list"
        android:layout_width="409dp"
        android:layout_height="729dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:paddingLeft="40dp"
        android:paddingRight="30dp"/>
</androidx.constraintlayout.widget.ConstraintLayout>
<?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="match_parent"
    android:orientation="vertical">

    <TextView
        android:id="@+id/time_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

    <TextView
        android:id="@+id/Minutes_1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
    <TextView
        android:id="@+id/text_1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

    <TextView
        android:id="@+id/minutes_2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
    <TextView
        android:id="@+id/text_2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

    <TextView
        android:id="@+id/minutes_3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
    <TextView
        android:id="@+id/text_3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

    <TextView
        android:id="@+id/minutes_4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
    <TextView
        android:id="@+id/text_4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
</LinearLayout>

区切り線がデフォルトで横いっぱいになるので左右を開けてテキスト表示と同じ並びにしたいときは以下の設定をするとうまくいく。左右が空いているのがわかると思う。

android:insetLeft=”26dp”
android:insetRight=”26dp”

でスペースを設定している。

<?xml version="1.0" encoding="utf-8"?>
<!-- 四角の色付きバックを描く-->
<inset xmlns:android="http://schemas.android.com/apk/res/android"
    android:insetLeft="26dp"
    android:insetRight="26dp"
    >
    <shape>
        <solid android:color="#cccccc" />
        <size android:height="1dp" />
    </shape>

</inset>

    <!-- 下線を引く
    <shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="line" >
        <stroke
            android:width="1dp"
            android:color="#ff0000" />
    </shape>
    -->
<!--左右を開けるラインを引く-->

上のlist_divider.xmlを入れる場合は以下のように記述し必要なところに入れるだけ。

android:background=”@drawable/list_divider”

package com.example.csvreadsample;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.widget.ListView;

public class MainActivity extends AppCompatActivity {

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

        CsvReader parser = new CsvReader();
        parser.reader(getApplicationContext());
        ListViewAdapter listViewAdapter = new ListViewAdapter(this, 0, parser.objects);
        ListView listView = (ListView)findViewById(R.id.list);//activity_main.xmlのlistを読み込んでいる
        listView.setAdapter(listViewAdapter);
    }
}
package com.example.csvreadsample;

import android.content.Context;
import android.content.res.AssetManager;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

public class CsvReader {
    List<ListData> objects = new ArrayList<ListData>();
    public void reader(Context context) {
        AssetManager assetManager = context.getResources().getAssets();
        try {
            // CSVファイルの読み込み
            InputStream inputStream = assetManager.open("test.csv");
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
            BufferedReader bufferReader = new BufferedReader(inputStreamReader);
            String line;
            while ((line = bufferReader.readLine()) != null) {

                //カンマ区切りで1つづつ配列に入れる
                ListData data = new ListData();
                String[] RowData = line.split(",");

                //CSVの左([0]番目)から順番にセット
                data.setTime_name(RowData[0]);
                data.setMinutes_1(RowData[1]);
                data.setText_1(RowData[2]);
                data.setMinutes_2(RowData[3]);
                data.setText_2(RowData[4]);
                data.setMinutes_3(RowData[5]);//これを入れるとアプリが落ちる
                data.setText_3(RowData[6]);
                data.setMinutes_4(RowData[7]);//これを入れるとアプリが落ちる
                data.setText_4(RowData[8]);

                objects.add(data);
            }
            bufferReader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
package com.example.csvreadsample;

public class ListData {
    String time_name;
    String minutes_1;
    String text_1;
    String minutes_2;
    String text_2;
    String minutes_3;
    String text_3;
    String minutes_4;
    String text_4;//この下の方に入れるとグレーでなくなる

    //時間
    public void setTime_name(String time_name){
        this.time_name = time_name;
    }
    public String getTime_name(){
        return time_name;
    }

    //分
    public void setMinutes_1 (String minutes_1){
        this.minutes_1 = minutes_1;
    }
    public String getMinutes_1(){
        return minutes_1;
    }

    //行く先
    public void setText_1(String text_1){
        this.text_1 = text_1;
    }
    public  String getText_1(){
        return text_1;
    }

    //分
    public void setMinutes_2(String minutes_2){
        this.minutes_2 = minutes_2;
    }
    public String getMinutes_2(){
        return minutes_2;
    }

    //行く先
    public void setText_2(String text_2){
        this.text_2 = text_2;
    }
    public String getText_2(){
        return text_2;
    }

    //分
    public void setMinutes_3(String minutes_3){
        this.minutes_3 = minutes_3;
    }
    public String getMinutes_3(){
        return minutes_3;
    }

    //行く先
    public void setText_3(String text_3){
        this.text_3 = text_3;
    }
    public String getText_3(){
        return text_3;
    }

    //分
    public void setMinutes_4(String minutes_4){
        this.minutes_4 = minutes_4;
    }
    public String getMinutes_4(){
        return minutes_4;
    }
    //行く先
    public void setText_4(String text_4){
        this.text_4 = text_4;
    }
    public String getText_4(){
        return text_4;
    }

    // ここの分はいくら追加してもエラーにはならない
}
package com.example.csvreadsample;

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

import androidx.annotation.NonNull;

import java.util.List;

public class ListViewAdapter extends ArrayAdapter<ListData> {
    private final LayoutInflater layoutInflater;

    public ListViewAdapter(Context context, int resource, List<ListData> objects) {
        super(context, resource, objects);
        layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @NonNull
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ListData data = (ListData)getItem(position);
        if (null == convertView) {
            convertView = layoutInflater.inflate(R.layout.list_item, null);
        }

        TextView time_nameText;
        TextView minutes_1Text;
        TextView text_1Text;
        TextView minutes_2Text;
        TextView text_2Text;
        TextView minutes_3Text;
        TextView text_3Text;
        TextView minutes_4Text;
        TextView text_4Text;

        time_nameText = (TextView)convertView.findViewById(R.id.time_name);
        minutes_1Text = (TextView)convertView.findViewById(R.id.Minutes_1);
        text_1Text = (TextView)convertView.findViewById(R.id.text_1);
        minutes_2Text = (TextView)convertView.findViewById(R.id.minutes_2);
        text_2Text = (TextView)convertView.findViewById(R.id.text_2);
        minutes_3Text = (TextView)convertView.findViewById(R.id.minutes_3);
        text_3Text = (TextView)convertView.findViewById(R.id.text_3);
        minutes_4Text = (TextView)convertView.findViewById(R.id.minutes_4);
        text_4Text = (TextView)convertView.findViewById(R.id.text_4);

        time_nameText.setText(data.getTime_name());
        minutes_1Text.setText(data.getMinutes_1());
        text_1Text.setText(data.getText_1());
        minutes_2Text.setText(data.getMinutes_2());
        text_2Text.setText(data.getText_2());
        minutes_3Text.setText(data.getMinutes_3());
        text_3Text.setText(data.getText_3());
        minutes_4Text.setText(data.getMinutes_4());
        text_4Text.setText(data.getText_4());

        return convertView;
    }
}

リスト数の追加方法

チョット面倒な作業がまっているが、内容は単純である。

list_item.xml

赤枠が追加するワンブロック、それぞれ追加するなら3のところを4にする。
idはそれぞれ、「minutes_4」「text_4」となる。

ListData.java

変数の宣言を入れる
コピーして追加「String minutes_4;」「String text_4;」に変更。

同じく下の方にある、赤枠部分をコピーして「3」を「4」に変更。

ListViewAdapter.java

赤枠部分をコピーして追加、「3」を「4」に変更。

レイアウトを少し拡張してみた

以下の設定に変更すると、分の時間とその後に行く先を横並びにすることができる。さらに先頭の時間はテキストを大きく、バックに色を入れている。

<?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="match_parent"
    android:orientation="vertical">

    <!--時間表示-->
    <TextView
        android:id="@+id/time_name"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textSize="30dp"
        android:textStyle="bold"
        android:background="#f0e68c"
        android:paddingStart="20dp"
        android:layout_marginStart="10dp"
        android:layout_marginEnd="10dp"
        android:layout_marginTop="10dp"/>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center_vertical"
        android:orientation="horizontal">
        <!--分表示-->
        <TextView
            android:id="@+id/Minutes_1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="20dp"
            android:textStyle="bold"
            android:layout_marginStart="50dp"
            android:layout_marginEnd="40dp"/>

        <!--行く先表示-->
        <TextView
            android:id="@+id/text_1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="0dp"
            android:layout_marginEnd="0dp" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center_vertical"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/minutes_2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="20dp"
            android:textStyle="bold"
            android:layout_marginStart="50dp"
            android:layout_marginEnd="40dp"/>

        <TextView
            android:id="@+id/text_2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="0dp"
            android:layout_marginEnd="0dp"/>
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center_vertical"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/minutes_3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="20dp"
            android:textStyle="bold"
            android:layout_marginStart="50dp"
            android:layout_marginEnd="40dp"/>

        <TextView
            android:id="@+id/text_3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="0dp"
            android:layout_marginEnd="0dp"/>
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center_vertical"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/minutes_4"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="20dp"
            android:textStyle="bold"
            android:layout_marginStart="50dp"
            android:layout_marginEnd="40dp"/>

        <TextView
            android:id="@+id/text_4"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="0dp"
            android:layout_marginEnd="0dp"/>
    </LinearLayout>
</LinearLayout>