Android でスピナーを開閉するときに、矢印のアイコンをアニメーション化する必要があります。スピナーを開くときに矢印を回転させることができsetOnTouchListener
ますSpinner
。
そのアクションでリスナーなどを設定する方法がわからないため、ドロップダウンが閉じているか非表示になっているときに問題が発生します。
可能であれば、これを行う方法について誰かが考えていますか?
よろしくお願いします。
Android でスピナーを開閉するときに、矢印のアイコンをアニメーション化する必要があります。スピナーを開くときに矢印を回転させることができsetOnTouchListener
ますSpinner
。
そのアクションでリスナーなどを設定する方法がわからないため、ドロップダウンが閉じているか非表示になっているときに問題が発生します。
可能であれば、これを行う方法について誰かが考えていますか?
よろしくお願いします。
Google がこれほど長くできない理由はわかりませんが、次の方法で問題を解決できます。
Spinner の保護されたメソッド「onDetachedFromWindow」をオーバーライドし、パブリック メソッドとして作成し、CustomSpinnerAdapter の項目をクリックして呼び出す必要があります。
例えば:
public class CustomSpinner extends Spinner
{
Context context = null;
public CustomSpinner(Context context)
{
super(context);
}
public CustomSpinner(Context context, int mode)
{
super(context, mode);
}
public CustomSpinner(Context context, AttributeSet attrs)
{
super(context, attrs);
}
public CustomSpinner(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
}
public CustomSpinner(Context context, AttributeSet attrs, int defStyle, int mode)
{
super(context, attrs, defStyle, mode);
}
@Override public void onDetachedFromWindow()
{
super.onDetachedFromWindow();
}
}
SpinnerCustomAdapter を作成し、この CustomSpinner を xml に挿入する方法を理解していただければ幸いです。
あなたはこのようなことをすることができます、
boolean bflag=true;//declare it as public
spinner.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View arg0, MotionEvent arg1) {
// TODO Auto-generated method stub
if(bflag==true)
{
//first animation code goes here
Toast.makeText(getActivity(), "on", Toast.LENGTH_SHORT).show();
bflag=false;
}
else
{
//second animation code goes here
Toast.makeText(getActivity(), "off", Toast.LENGTH_SHORT).show();
bflag=true;
}
return false;
}
});
リフレクションを使用し、プライベート フィールド'mPopup'にアクセスしてから、メソッドsetOnDismissListener()を設定する必要があります。これは、ユーザーが空の領域をクリックしたり、新しい項目を選択したりしても、ポップアップが閉じられたときにトリガーされます。ここでその仕組みについて詳しく知ることができます: https://stackoverflow.com/a/69156679/3753104
カスタム Spinner の完全なソース コードは次のとおりです。
open class CustomSpinner: androidx.appcompat.widget.AppCompatSpinner {
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
lateinit var listPopupWindow: ListPopupWindow
lateinit var onPopUpClosedListener: (dropDownMenu: DropDownMenu) -> Unit
lateinit var onPopUpOpenedListener: (dropDownMenu: DropDownMenu) -> Unit
init {
try {
// get the listPopupWindow
val listPopupWindowField = androidx.appcompat.widget.AppCompatSpinner::class.java.getDeclaredField("mPopup")
listPopupWindowField.isAccessible = true
listPopupWindow = listPopupWindowField.get(this) as ListPopupWindow
listPopupWindow.isModal = false
} catch (e: Exception) {
e.printStackTrace()
}
}
override fun performClick(): Boolean {
val returnValue = super.performClick()
// indicate that the pop-up was opened
if (::onPopUpOpenedListener.isInitialized) {
onPopUpOpenedListener.invoke(this)
}
try {
// get the popupWindow
val popupWindowField = ListPopupWindow::class.java.getDeclaredField("mPopup")
popupWindowField.isAccessible = true
val popupWindow = popupWindowField.get(listPopupWindow) as PopupWindow
// get the original onDismissListener
val onDismissListenerField = PopupWindow::class.java.getDeclaredField("mOnDismissListener")
onDismissListenerField.isAccessible = true
val onDismissListener = onDismissListenerField.get(popupWindow) as PopupWindow.OnDismissListener
// now override the original OnDismissListener
listPopupWindow.setOnDismissListener {
// indicate that the pop-up was closed
if (::onPopUpClosedListener.isInitialized) {
onPopUpClosedListener.invoke(this)
}
// now we need to call the original listener that will remove the global OnLayoutListener
onDismissListener.onDismiss()
}
} catch (e: Exception) {
e.printStackTrace()
}
return returnValue
}
}
そして、リスナーをカスタム スピナーにアタッチするだけです。
val customSpinner = findViewById<CustomSpinner>(R.id.mySpinner)
customSpinner.onPopUpClosedListener = {
// called when the pop-up is closed
}
customSpinner.onPopUpOpenedListener = {
// called when the pop-up is opened
}
この方法を試してください
spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
// // called when spiner will closed
}
@Override
public void onNothingSelected(AdapterView<?> arg0) {
// called when spiner will closed
}
});