「選択された」ビューをグローバル変数として保存し、フォーカスが変更されたときにそれを削除するのはどうですか? focusable
、focusableInTouchMode
およびonClick
リスナーをいじることで、適切な結果が得られる可能性があります。それが最善の解決策かどうかはわかりませんが、うまくいきます。
必要なもの:
- グローバル ビュー変数:
GridLayout
の子が選択された状態で長押しされました。
- (オプション) any としてのカスタム親コンテナー: すべての子[*]
ViewGroup
にフォーカス可能なリスナーを設定します。私のテストでは、 aと aを使用しました。LinearLayout
RelativeLayout
[*] オプションの親カスタム クラスを使用しない場合は、親 ViewGroup のすべての子に対して設定する必要がandroid:focusable="true"
あります。また、親の ViewGroup がクリックされたときに呼び出すためandroid:focusableInTouchMode="true"
に設定する必要があります。OnClickListener
removeViewSelected()
- 子のクリック リスナーの追加
GridLayout
: 選択したビューを更新します。
- フォーカス リスナーの実装: フォーカスが失われている場合、選択したビューを削除します。
親階層と子階層のすべてのフォーカス変更状態を処理します。出力を参照してください。
次のパターンを使用しました。
CoordinatorLayout --- simple root group
ParentLayout --- aka "parentlayout"
Button --- simple Button example
GridLayout --- aka "gridlayout"
FloattingActionButton --- simple Button example
View
で選択したメソッドとその更新メソッドを準備しましょうActivity
。
private View selectedView;
...
private void setViewSelected(View view) {
removeViewSelected();
selectedView = view;
if (selectedView != null) {
// change to a selected background for example
selectedView.setBackgroundColor(
ContextCompat.getColor(this, R.color.colorAccent));
}
}
private View getViewSelected() {
if (selectedView != null) {
return selectedView;
}
return null;
}
private void removeViewSelected() {
if (selectedView != null) {
// reset the original background for example
selectedView.setBackgroundResource(R.drawable.white_with_borders);
selectedView = null;
}
// clear and reset the focus on the parent
parentlayout.clearFocus();
parentlayout.requestFocus();
}
GridLayout
子ごとに、Click
およびLongClick
リスナーを追加して、選択したビューを更新または削除します。私TextView
のものは動的に追加されましたが、for ループを簡単に作成して子を取得できます。
TextView tv = new TextView(this);
...
gridlayout.addView(tv);
tv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
removeViewSelected();
}
});
tv.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
setViewSelected(view);
return true;
}
});
FocusChange
親コンテナにリスナーを設定します。
parentlayout.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View view, boolean hasFocus) {
View viewSelected = getViewSelected();
// if the selected view exists and it lost focus
if (viewSelected != null && !viewSelected.hasFocus()) {
// remove it
removeViewSelected();
}
}
});
次に、オプションの custom : XML とリスナーによって状態を動的にViewGroup
設定できるためオプションですが、私には簡単に思えます。この次のカスタムを親コンテナーとして 使用しました。focusable
clickable
Class
public class ParentLayout extends RelativeLayout implements View.OnClickListener {
public ParentLayout(Context context) {
super(context);
init();
}
public ParentLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public ParentLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
// handle focus and click states
public void init() {
setFocusable(true);
setFocusableInTouchMode(true);
setOnClickListener(this);
}
// when positioning all children within this
// layout, add their focusable state
@Override
protected void onLayout(boolean c, int l, int t, int r, int b) {
super.onLayout(c, l, t, r, b);
final int count = getChildCount();
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
child.setFocusable(true);
child.setFocusableInTouchMode(true);
}
// now, even the Button has a focusable state
}
// handle the click events
@Override
public void onClick(View view) {
// clear and set the focus on this viewgroup
this.clearFocus();
this.requestFocus();
// now, the focus listener in Activity will handle
// the focus change state when this layout is clicked
}
}
たとえば、これは私が使用したレイアウトです。
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout ...>
<com.app.ParentLayout
android:id="@+id/parent_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal">
<Button
android:id="@+id/sample_button"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"
android:text="A Simple Button"
android:layout_marginTop="20dp"
android:layout_marginBottom="20dp"/>
<android.support.v7.widget.GridLayout
android:id="@+id/grid_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:layout_above="@id/sample_button" .../>
</com.app.ParentLayout>
<android.support.design.widget.FloatingActionButton .../>
</android.support.design.widget.CoordinatorLayout>
これが役立つことを願っています。