最近ハマった事象の備忘録(SupporLibrary編2)
はじめに
前回のまとめは
最近ハマった事象の備忘録(SupporLibrary編) - exception think
古いアプリをマテリアルデザイン化に簡単にしようとすると
- SnackBarを使う
- AppCompatXXX 系の部品を使う
- AppCompatSpinner とか
- BottomSheetDialogを使う
あたりになるわけですが、ココらへんに関してハマった話をメモしておこうかと
SnackBar編
SnackBarの表示初期化中にBackKeyで戻ったりするとアプリが落ちる
Toastの代わりにSnackBarを使いましょう みたいなお話がじつはあったりしますが
これSnackBarの表示初期化中にBackKeyで戻ったりするとアプリが落ちます*1
シーケンシャルスレッド処理ではないからでしょうね・・
public void infoBar(int resID){ infoBar(getString(resId)); } public void infoBar(String msg){ View parent = findViewById(R.id.actionBar); if(parent == null){ Toast.makeText(this, msg, Toast.LENGTH_LONG).show(); } else{ Snackbar snackbar = Snackbar.make(parent, msg, Snackbar.LENGTH_LONG); snackbar.show(); } }
な感じでコンパチにしておくのがベターかな~
同じような話で
data-binding で下記のようなコードが合ったりしますが
これも表示中にキャンセルすると、executePendingBindings で落ちるので
try-catchしておくのがよいかと。避けようがないので・・
- NG
@Override public void onBindViewHolder(ItemViewHolder holder, int position) { User user = mUserList.get(position); // Userデータをセット。BR.userはxmlのvariableの名前 holder.getBinding().setVariable(BR.user, user); holder.getBinding().executePendingBindings(); }
@Override public void onBindViewHolder(ItemViewHolder holder, int position) { User user = mUserList.get(position); // Userデータをセット。BR.userはxmlのvariableの名前 holder.getBinding().setVariable(BR.user, user); try{ holder.getBinding().executePendingBindings(); }catch(Exception ex){ } }
SnackBarの文字が黒字でみえないことが有る
AppCompatのstyle.xmlが新し目のものは整備されているのですが、
4系とかそれ以前のものだとstyle.xml がデフォルトでちゃんと用意されていないので、背景が黒、文字も黒で見えない みたいな話になります
前回の話の AlertDialogと同じ話ですね。。
SnackBar自体の色は基本 黒のようなので、文字色だけ明示的に指定するようにします
Snackbar snackbar = Snackbar.make(view, msg, Snackbar.LENGTH_LONG); View view = snackbar.getView(); TextView tv = (TextView) view.findViewById(android.support.design.R.id.snackbar_text); tv.setTextColor(Color.WHITE); snackbar.show();
参考
AppCompatSpinnerの選択状態
android:entriesを設定している場合、
selection処理とentries初期化処置がかち合ってしまうのでDelayかける必要が有り
- layout.xml
<android.support.v7.widget.AppCompatSpinner android:entries="@array/list_items" android:id="@+id/spinner" android:layout_width="match_parent" android:layout_height="wrap_content">
- NG
AppCompatSpinner spinner = (AppCompatSpinner) findViewById(R.id.spinner);
spinner.setSelection(0);
final AppCompatSpinner spinner = (AppCompatSpinner) findViewById(R.id.spinner); spinner.postDelayed(new Runnable() { @Override public void run() { spinner.setSelection(0); } });
BottomSheetDialogについて
BottomSheetDialog mBottomSheetDialog = new BottomSheetDialog(getActivity()); View view = XXX; //★ mBottomSheetDialog.setContentView(view); mBottomSheetDialog.show();
★の部分はよく RecyclerViewのサンプルがググるとでてきますが、
単なるViewですので、もちろんListViewでもOK
ただもちろん
- バックグラウンド背景が黒透明になるのを透明にできない
- Dialogなので仕方ない
- FloatingActionButtonと連動できない
- CoordinatorLayout + BottomSheetBehavior を使うことは出来ない
- 其の場合は、layout上に BottomSheetにしたいViewに属性を追加する
下記のようにレイアウトべた書きになる事を、企画デザインの方に説明しておかないと
結構勘違いされることになります。。
<?xml version="1.0" encoding="utf-8"?> <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/coordinator_layout" tools:context=".MainActivity" > <!--BottomSheetで使いたいレイアウト --> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" app:layout_behavior="@string/bottom_sheet_behavior" //★ app:behavior_peekHeight="200dp" //★ android:background="@android:color/white"> </LinearLayout> <!--CoordinatorLayoutと連動するFabボタン --> <android.support.design.widget.FloatingActionButton android:id="@+id/fab" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_add_white_24dp" design:fabSize="normal" design:layout_anchor="@id/coordinator_layout" //★ design:layout_anchorGravity="bottom|right" //★ /> </android.support.design.widget.CoordinatorLayout>
BottomSheetBehavior自体は、BottomSheetDialogでも使えるんですけどね。。
dialog.setContentView(view); BottomSheetBehavior mBehavior = BottomSheetBehavior.from((View) view.getParent()); mBehavior.setPeekHeight(300);//表示初期高さサイズ dialog.show();
*1:parentのViewが参照エラーで