SQLの窓

2016年09月27日


Android : Data Binding + Firebase API で ListView にデータを表示する

ListView の扱いとしては、『Android : Data Binding で ListView へのデータ表示を凄く簡単にする』 の拡張です。

Firebase 部分のセットアップは、『Firebase API + Android Studio : Database 処理の基本設定』を参照して下さい。

Firebase API で Databaseデータ を読み込む方法に関しては『Firebase API + Android Studio : Database のデータを Java に取得する方法は3通りあります。』を参照して下さい

Firebase の ArrayList データを使用したソース
public class MainActivity extends Activity {

	private FirebaseDatabase database;
	private DatabaseReference mDatabase;
	private ArrayList<Item> users;
	private User user;

	TestArrayAdapter<Item> adapter = null;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		database = FirebaseDatabase.getInstance();
		mDatabase = database.getReference();

		ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
		user = new User();
		user.setFirstName("山田");
		user.setLastName("タロウ");
		binding.setUser(user);

		adapter = new TestArrayAdapter<Item>(
				MainActivity.this,
				R.layout.myitem,
				new TestArrayAdapter.OnGetViewListener() {
					@Override
					public View onGetViewListener(int position, View convertView, ViewGroup parent) {

						MyitemBinding myitem;

						if ( convertView == null ) {
							LayoutInflater inflater = (LayoutInflater) MainActivity.this.getSystemService
								(Context.LAYOUT_INFLATER_SERVICE);
							myitem = DataBindingUtil.inflate(inflater, R.layout.myitem, parent, false);
						}
						else {
							myitem = DataBindingUtil.getBinding(convertView);
						}


						ListView lv = (ListView)parent;
						TestArrayAdapter taa = (TestArrayAdapter)lv.getAdapter();
						myitem.setItem(  taa.getItem(position) );

						// ここが重要です
						return myitem.getRoot();
					}
				}
		);

		((ListView)MainActivity.this.findViewById(R.id.listView)).setAdapter(adapter);

		// Firebase Database より読み込み
		MainActivity.this.findViewById(R.id.buttonFirebase).setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {

				mDatabase.child("users").addListenerForSingleValueEvent(new ValueEventListener() {
					@Override
					public void onDataChange(DataSnapshot dataSnapshot) {
						if ( dataSnapshot.exists() ) {
							Log.i("lightbox", dataSnapshot.getValue().toString());

							GenericTypeIndicator<ArrayList<Item>> t = new GenericTypeIndicator<ArrayList<Item>>() {};
							users = dataSnapshot.getValue(t);

							adapter.clear();
							adapter.addAll(users);

						}
						else {
							Log.i("lightbox","データを読み込めませんでした");
						}
					}

					@Override
					public void onCancelled(DatabaseError databaseError) {
						Log.i("lightbox","onCancelled");
						StringWriter sw = new StringWriter();
						PrintWriter pw = new PrintWriter(sw);
						databaseError.toException().printStackTrace(pw);
						pw.flush();
						String stackTrace = sw.toString();
						Log.i("lightbox",stackTrace);

					}
				});
			}
		});

		// ボタンを押して、オブジェクトの変更のみで反映されます
		MainActivity.this.findViewById(R.id.buttonSetValue).setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				user.setFirstName("鈴木");
				user.setLastName("ジロウ");
				if ( users != null ) {
					users.get(0).setText("getView での記述が簡単になりました");
					users.get(1).setText("しかも、オブジェクトを変更すると ListView も変わります");
				}
			}
		});
	}

	// バインド用クラス(1)
	public static class User extends BaseObservable {
		private String firstName;
		private String lastName;

		@Bindable
		public String getFirstName() {
			return this.firstName;
		}
		@Bindable
		public String getLastName() {
			return this.lastName;
		}

		public void setFirstName(String firstName) {
			this.firstName = firstName;
			notifyPropertyChanged(sample.lightbox.myapplication.BR.firstName);
		}
		public void setLastName(String lastName) {
			this.lastName = lastName;
			notifyPropertyChanged(sample.lightbox.myapplication.BR.lastName);
		}
	}

	// バインド用クラス(2) : ListView 用
	public static class Item extends BaseObservable {
		private String title;
		private String text;
		private boolean flg = false;

		public Item() {}

		public Item(String text,String title) {
			this.text = text;
			this.title = title;
		}

		@Bindable
		public String getText() {
			return this.text;
		}
		@Bindable
		public String getTitle() {
			return this.title;
		}

		public void setText(String text) {
			this.text = text;
			notifyPropertyChanged(sample.lightbox.myapplication.BR.text);
		}

		public void seTitle(String title) {
			this.title = title;
			notifyPropertyChanged(sample.lightbox.myapplication.BR.title);
		}

		public String getCode() {
			return title;
		}
		public String getName() {
			return text;
		}
		public void setCode(String code) {
			this.title = code;
		}
		public void setName(String name) {
			this.text = name;
		}

	}

}

Item クラスに、Firebase で定義したデータを使用する為に、Firebase 用の Setter を作成して、元々のデータ処理と互換性を持たせています。

setText と setTitle 側で、notifyPropertyChanged を使っているので、そちらでデータの変更を行っています。

このデータは、以下のようなフォーマットであり、ArrayList として直接取得しています。



しかし、個別のデータとしては上記データは特殊な部類になるので、以下のようなデータで ListView にデータをセットします。



Firebase の HashMap データを使用したソース
public class MainActivity extends Activity {

	private FirebaseDatabase database;
	private DatabaseReference mDatabase;
	private HashMap<String,Item> users;
	private ArrayList<Item> userList;
	private User user;

	TestArrayAdapter<Item> adapter = null;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		database = FirebaseDatabase.getInstance();
		mDatabase = database.getReference();

		ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
		user = new User();
		user.setFirstName("山田");
		user.setLastName("タロウ");
		binding.setUser(user);

		adapter = new TestArrayAdapter<Item>(
				MainActivity.this,
				R.layout.myitem,
				new TestArrayAdapter.OnGetViewListener() {
					@Override
					public View onGetViewListener(int position, View convertView, ViewGroup parent) {

						MyitemBinding myitem;

						if ( convertView == null ) {
							LayoutInflater inflater = (LayoutInflater) MainActivity.this.getSystemService
								(Context.LAYOUT_INFLATER_SERVICE);
							myitem = DataBindingUtil.inflate(inflater, R.layout.myitem, parent, false);
						}
						else {
							myitem = DataBindingUtil.getBinding(convertView);
						}

						ListView lv = (ListView)parent;
						TestArrayAdapter taa = (TestArrayAdapter)lv.getAdapter();
						myitem.setItem(  taa.getItem(position) );

						// ここが重要です
						return myitem.getRoot();
					}
				}
		);

		((ListView)MainActivity.this.findViewById(R.id.listView)).setAdapter(adapter);

		// Firebase Database より読み込み
		MainActivity.this.findViewById(R.id.buttonFirebase).setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {

				mDatabase.child("class").addListenerForSingleValueEvent(new ValueEventListener() {
					@Override
					public void onDataChange(DataSnapshot dataSnapshot) {
						if ( dataSnapshot.exists() ) {
							Log.i("lightbox", dataSnapshot.getValue().toString());

							GenericTypeIndicator<HashMap<String,Item>> t = new GenericTypeIndicator<HashMap<String,Item>>() {};
							users = dataSnapshot.getValue(t);

							// 必要ならば、ここでデータ順序の変更が必要です
							userList = new ArrayList<Item>(users.values());

							adapter.clear();
							adapter.addAll(userList);

						}
						else {
							Log.i("lightbox","データを読み込めませんでした");
						}
					}

					@Override
					public void onCancelled(DatabaseError databaseError) {
						Log.i("lightbox","onCancelled");
						StringWriter sw = new StringWriter();
						PrintWriter pw = new PrintWriter(sw);
						databaseError.toException().printStackTrace(pw);
						pw.flush();
						String stackTrace = sw.toString();
						Log.i("lightbox",stackTrace);

					}
				});
			}
		});

		// ボタンを押して、オブジェクトの変更のみで反映されます
		MainActivity.this.findViewById(R.id.buttonSetValue).setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				user.setFirstName("鈴木");
				user.setLastName("ジロウ");
				if ( userList != null ) {
					userList.get(0).setText("getView での記述が簡単になりました");
					userList.get(1).setText("しかも、オブジェクトを変更すると ListView も変わります");
				}
			}
		});
	}

	// バインド用クラス(1)
	public static class User extends BaseObservable {
		private String firstName;
		private String lastName;

		@Bindable
		public String getFirstName() {
			return this.firstName;
		}
		@Bindable
		public String getLastName() {
			return this.lastName;
		}

		public void setFirstName(String firstName) {
			this.firstName = firstName;
			notifyPropertyChanged(sample.lightbox.myapplication.BR.firstName);
		}
		public void setLastName(String lastName) {
			this.lastName = lastName;
			notifyPropertyChanged(sample.lightbox.myapplication.BR.lastName);
		}
	}

	// バインド用クラス(2) : ListView 用
	public static class Item extends BaseObservable {
		private String title;
		private String text;
		private boolean flg = false;

		public Item() {}

		public Item(String text,String title) {
			this.text = text;
			this.title = title;
		}

		@Bindable
		public String getText() {
			return this.text;
		}
		@Bindable
		public String getTitle() {
			return this.title;
		}

		public void setText(String text) {
			this.text = text;
			notifyPropertyChanged(sample.lightbox.myapplication.BR.text);
		}

		public void seTitle(String title) {
			this.title = title;
			notifyPropertyChanged(sample.lightbox.myapplication.BR.title);
		}

		public String getCode() {
			return title;
		}
		public String getName() {
			return text;
		}
		public void setCode(String code) {
			this.title = code;
		}
		public void setName(String name) {
			this.text = name;
		}

	}

}




【2016 Android Studioの最新記事】
posted by lightbox at 2016-09-27 20:36 | 2016 Android Studio | このブログの読者になる | 更新情報をチェックする
container 終わり



フリーフォントで簡単ロゴ作成
フリーフォントでボタン素材作成
フリーフォントで吹き出し画像作成
フリーフォントではんこ画像作成
ほぼ自由に利用できるフリーフォント
フリーフォントの書体見本とサンプル
画像を大きく見る為のウインドウを開くボタンの作成

CSS ドロップシャドウの参考デモ
イラストAC
ぱくたそ
写真素材 足成
フリーフォント一覧
utf8 文字ツール
右サイド 終わり
base 終わり