【问题标题】:Android - Movable/Draggable Floating Action Button (FAB)Android - 可移动/可拖动的浮动操作按钮 (FAB)
【发布时间】:2018-03-04 09:27:51
【问题描述】:

我在我的应用程序中使用FloatingActionButton。有时,它会与基本内容重叠,所以我想制作它以便用户可以将 FAB 拖到一边。

本身不需要拖放功能。它只需要是可移动的。文档没有提到这一点,但我确信我在其他应用程序中看到过这样的功能。

任何人都可以建议/提供有关如何执行此操作的代码 sn-p(最好是 XML 格式)。

【问题讨论】:

    标签: android floating-action-button


    【解决方案1】:

    基于this answer for another SO question 这是我创建的代码。它似乎工作得很好(具有工作点击功能)并且不依赖于 FAB 的父布局或定位......

    package com.example;
    
    import android.content.Context;
    import android.support.design.widget.FloatingActionButton;
    import android.util.AttributeSet;
    import android.view.MotionEvent;
    import android.view.View;
    import android.view.ViewGroup;
    
    public class MovableFloatingActionButton extends FloatingActionButton implements View.OnTouchListener {
    
        private final static float CLICK_DRAG_TOLERANCE = 10; // Often, there will be a slight, unintentional, drag when the user taps the FAB, so we need to account for this.
    
        private float downRawX, downRawY;
        private float dX, dY;
    
        public MovableFloatingActionButton(Context context) {
            super(context);
            init();
        }
    
        public MovableFloatingActionButton(Context context, AttributeSet attrs) {
            super(context, attrs);
            init();
        }
    
        public MovableFloatingActionButton(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            init();
        }
    
        private void init() {
            setOnTouchListener(this);
        }
    
        @Override
        public boolean onTouch(View view, MotionEvent motionEvent){
    
            ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams)view.getLayoutParams();
    
            int action = motionEvent.getAction();
            if (action == MotionEvent.ACTION_DOWN) {
    
                downRawX = motionEvent.getRawX();
                downRawY = motionEvent.getRawY();
                dX = view.getX() - downRawX;
                dY = view.getY() - downRawY;
    
                return true; // Consumed
    
            }
            else if (action == MotionEvent.ACTION_MOVE) {
    
                int viewWidth = view.getWidth();
                int viewHeight = view.getHeight();
    
                View viewParent = (View)view.getParent();
                int parentWidth = viewParent.getWidth();
                int parentHeight = viewParent.getHeight();
    
                float newX = motionEvent.getRawX() + dX;
                newX = Math.max(layoutParams.leftMargin, newX); // Don't allow the FAB past the left hand side of the parent
                newX = Math.min(parentWidth - viewWidth - layoutParams.rightMargin, newX); // Don't allow the FAB past the right hand side of the parent
    
                float newY = motionEvent.getRawY() + dY;
                newY = Math.max(layoutParams.topMargin, newY); // Don't allow the FAB past the top of the parent
                newY = Math.min(parentHeight - viewHeight - layoutParams.bottomMargin, newY); // Don't allow the FAB past the bottom of the parent
    
                view.animate()
                        .x(newX)
                        .y(newY)
                        .setDuration(0)
                        .start();
    
                return true; // Consumed
    
            }
            else if (action == MotionEvent.ACTION_UP) {
    
                float upRawX = motionEvent.getRawX();
                float upRawY = motionEvent.getRawY();
    
                float upDX = upRawX - downRawX;
                float upDY = upRawY - downRawY;
    
                if (Math.abs(upDX) < CLICK_DRAG_TOLERANCE && Math.abs(upDY) < CLICK_DRAG_TOLERANCE) { // A click
                    return performClick();
                }
                else { // A drag
                    return true; // Consumed
                }
    
            }
            else {
                return super.onTouchEvent(motionEvent);
            }
    
        }
    
    }
    

    这里是 XML...

        <com.example.MovableFloatingActionButton
            android:id="@+id/fab"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom|end"
            android:layout_margin="@dimen/fab_margin"
            android:src="@drawable/ic_navigate_next_white_24dp"/>
    

    基本上,您只需将 XML 中的 android.support.design.widget.FloatingActionButton 替换为 com.example.MovableFloatingActionButton

    【讨论】:

    • 是否在活动中添加了其他任何内容,但在尝试拖动屏幕时,fab 没有发生任何事情
    • 你在CoordinatorLayout中使用MovableFloatingActionButton吗?
    • 是的,它只是移动晶圆厂的大小,而不是整个页面
    • 您能否在新问题中发布您的问题和代码,然后在此处发布指向它的链接。
    • 当我尝试这个时,我只在红框空间内得到了一个可移动的晶圆厂。 红框是虚构的 i.stack.imgur.com/a5o9j.png
    【解决方案2】:

    试试这个:

    public class MainActivity extends AppCompatActivity implements View.OnTouchListener {
      float dX;
      float dY;
      int lastAction;
    
      @Override
      protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        final View dragView = findViewById(R.id.draggable_view);
        dragView.setOnTouchListener(this);
      }
    
      @Override
      public boolean onTouch(View view, MotionEvent event) {
        switch (event.getActionMasked()) {
          case MotionEvent.ACTION_DOWN:
            dX = view.getX() - event.getRawX();
            dY = view.getY() - event.getRawY();
            lastAction = MotionEvent.ACTION_DOWN;
            break;
    
          case MotionEvent.ACTION_MOVE:
            view.setY(event.getRawY() + dY);
            view.setX(event.getRawX() + dX);
            lastAction = MotionEvent.ACTION_MOVE;
            break;
    
          case MotionEvent.ACTION_UP:
            if (lastAction == MotionEvent.ACTION_DOWN)
              Toast.makeText(DraggableView.this, "Clicked!", Toast.LENGTH_SHORT).show();
            break;
    
          default:
            return false;
        }
        return true;
      }
    }
    

    还有 XML:

    <ImageButton
            android:id="@+id/draggable_view"
            android:background="@mipmap/ic_launcher"
            android:layout_gravity="bottom|right"
            android:layout_marginBottom="20dp"
            android:layout_marginEnd="20dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
    

    您可以使任何视图可拖动和可点击。

    【讨论】:

      【解决方案3】:

      基于@ban-geoengineering 的回答,我更新为执行涟漪效应和左右重力,如 facebook 聊天气泡。我创建了自定义点击侦听器,因为如果在此代码块内使用触摸事件,则波纹效果无法清楚地工作。

          <com.sample.DraggableFloatingActionButton
          android:id="@+id/connect_to_support_fab"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:layout_gravity="bottom|end"
          android:layout_marginLeft="@dimen/spacing_10pt"
          android:layout_marginRight="@dimen/spacing_10pt"
          android:layout_marginBottom="@dimen/spacing_16pt"
          android:clickable="true"
          android:focusable="true"
          app:backgroundTint="@color/colorGreen"
          app:fabSize="normal"
          app:layout_constraintBottom_toBottomOf="parent"
          app:layout_constraintEnd_toEndOf="parent"
          app:rippleColor="@color/colorWhite"
          app:srcCompat="@drawable/ic_live_support"
          app:tint="@color/colorWhite" />
      
      package com.sample;
      
      import android.content.Context;
      import android.util.AttributeSet;
      import android.view.MotionEvent;
      import android.view.View;
      import android.view.ViewGroup;
      import android.view.animation.OvershootInterpolator;
      
      import com.google.android.material.floatingactionbutton.FloatingActionButton;
      
      public class DraggableFloatingActionButton extends FloatingActionButton implements View.OnTouchListener {
          CustomClickListener customClickListener;
      
          private final static float CLICK_DRAG_TOLERANCE = 10; // Often, there will be a slight, unintentional, drag when the user taps the FAB, so we need to account for this.
      
          private float downRawX, downRawY;
          private float dX, dY;
      
          int viewWidth;
          int viewHeight;
      
          int parentWidth;
          int parentHeight;
      
          float newX;
          float newY;
      
          public DraggableFloatingActionButton(Context context) {
              super(context);
              init();
          }
      
          public DraggableFloatingActionButton(Context context, AttributeSet attrs) {
              super(context, attrs);
              init();
          }
      
          public DraggableFloatingActionButton(Context context, AttributeSet attrs, int defStyleAttr) {
              super(context, attrs, defStyleAttr);
              init();
          }
      
          private void init() {
              setOnTouchListener(this);
          }
      
          @Override
          public boolean onTouch(View view, MotionEvent motionEvent) {
      
              ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) view.getLayoutParams();
      
              int action = motionEvent.getAction();
              if (action == MotionEvent.ACTION_DOWN) {
      
                  downRawX = motionEvent.getRawX();
                  downRawY = motionEvent.getRawY();
                  dX = view.getX() - downRawX;
                  dY = view.getY() - downRawY;
      
                  return false; // not Consumed for ripple effect
      
              } else if (action == MotionEvent.ACTION_MOVE) {
      
                  viewWidth = view.getWidth();
                  viewHeight = view.getHeight();
      
                  View viewParent = (View) view.getParent();
                  parentWidth = viewParent.getWidth();
                  parentHeight = viewParent.getHeight();
      
                  newX = motionEvent.getRawX() + dX;
                  newX = Math.max(layoutParams.leftMargin, newX); // Don't allow the FAB past the left hand side of the parent
                  newX = Math.min(parentWidth - viewWidth - layoutParams.rightMargin, newX); // Don't allow the FAB past the right hand side of the parent
      
                  newY = motionEvent.getRawY() + dY;
                  newY = Math.max(layoutParams.topMargin, newY); // Don't allow the FAB past the top of the parent
                  newY = Math.min(parentHeight - viewHeight - layoutParams.bottomMargin, newY); // Don't allow the FAB past the bottom of the parent
      
                  view.animate()
                          .x(newX)
                          .y(newY)
                          .setDuration(0)
                          .start();
      
                  return true; // Consumed
      
              } else if (action == MotionEvent.ACTION_UP) {
      
                  float upRawX = motionEvent.getRawX();
                  float upRawY = motionEvent.getRawY();
      
                  float upDX = upRawX - downRawX;
                  float upDY = upRawY - downRawY;
      
                  if (newX > ((parentWidth - viewWidth - layoutParams.rightMargin) / 2)) {
                      newX = parentWidth - viewWidth - layoutParams.rightMargin;
                  } else {
                      newX = layoutParams.leftMargin;
                  }
      
                  view.animate()
                          .x(newX)
                          .y(newY)
                          .setInterpolator(new OvershootInterpolator())
                          .setDuration(300)
                          .start();
      
                  if (Math.abs(upDX) < CLICK_DRAG_TOLERANCE && Math.abs(upDY) < CLICK_DRAG_TOLERANCE) { // A click
                      if (customClickListener != null) {
                          customClickListener.onClick(view);
                      }
                      return false;// not Consumed for ripple effect
                  } else { // A drag
                      return false; // not Consumed for ripple effect
                  }
      
              } else {
                  return super.onTouchEvent(motionEvent);
              }
      
          }
      
          public void setCustomClickListener(CustomClickListener customClickListener) {
              this.customClickListener = customClickListener;
          }
      
          public interface CustomClickListener {
              void onClick(View view);
          }
      
      }
      

      【讨论】:

      • 我尝试了它的工作。如何移动包含 fab 图标的布局。
      【解决方案4】:

      所有建议的答案都使用 OnTouch 侦听器,由于 Accessibility 实现,最近的 Android API 不推荐使用此侦听器。另请注意 startDrag() 方法已过时。开发人员应该使用 startDragAndDrop() 代替。 我的实现使用 OnDragListener() 如下:

      1. 定义两个全局浮点变量dX和dY;
      2. 将下面的sn-p放入onCreatView()方法中,其中root是根视图,由inflater(或任何其他可以接收Drop事件的视图)获取;

        final FloatingActionButton fab = root.findViewById(R.id.my_fab);
        
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // Do whatever this button will do on click event
            }
        });
        
        root.setOnDragListener(new View.OnDragListener() {
            @Override
            public boolean onDrag(View v, DragEvent event) {
                switch (event.getAction()) {
                    case DragEvent.ACTION_DRAG_LOCATION:
                        dX = event.getX();
                        dY = event.getY();
                        break;
                    case DragEvent.ACTION_DRAG_ENDED:
                        fab.setX(dX-fab.getWidth()/2);
                        fab.setY(dY-fab.getHeight()/2);
                        break;
                }
                return true;
            }
        });
        
        
        fab.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                View.DragShadowBuilder myShadow = new View.DragShadowBuilder(fab);
                v.startDragAndDrop(null, myShadow, null, View.DRAG_FLAG_GLOBAL);
                return true;
            }
        });
        

      【讨论】:

      • 很好的解决方案。立即工作,无需调试。我唯一需要改变的是,在我的例子中,我必须把它放在 OnCreate 中,而不是把它放在 OnCreateView 中。
      【解决方案5】:

      您可以通过在任何View 上实现onTouch 来尝试如下所示,

      xml

      <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="match_parent"
          android:id="@+id/rootlayout"
          android:layout_height="match_parent"
          android:orientation="vertical">
      
          <android.support.design.widget.FloatingActionButton
              android:id="@+id/fab"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content" />
      
      </FrameLayout>
      

      java

      public class dragativity extends AppCompatActivity implements View.OnTouchListener{
      
          FloatingActionButton fab;
      
          FrameLayout rootlayout;
      
           int _xDelta;
           int _yDelta;
      
          @Override
          protected void onCreate(@Nullable Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.drag);
      
              rootlayout = (FrameLayout) findViewById(R.id.rootlayout);
      
              fab = (FloatingActionButton) findViewById(R.id.fab);
      
              FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(150, 150);
              fab.setLayoutParams(layoutParams);
              fab.setOnTouchListener(dragativity.this);
          }
      
          public boolean onTouch(View view, MotionEvent event) {
              final int X = (int) event.getRawX();
              final int Y = (int) event.getRawY();
              switch (event.getAction() & MotionEvent.ACTION_MASK) {
                  case MotionEvent.ACTION_DOWN:
                      FrameLayout.LayoutParams lParams = (FrameLayout.LayoutParams) view.getLayoutParams();
                      _xDelta = X - lParams.leftMargin;
                      _yDelta = Y - lParams.topMargin;
                      break;
                  case MotionEvent.ACTION_UP:
                      break;
                  case MotionEvent.ACTION_POINTER_DOWN:
                      break;
                  case MotionEvent.ACTION_POINTER_UP:
                      break;
                  case MotionEvent.ACTION_MOVE:
                      FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) view
                              .getLayoutParams();
                      layoutParams.leftMargin = X - _xDelta;
                      layoutParams.topMargin = Y - _yDelta;
                      layoutParams.rightMargin = -250;
                      layoutParams.bottomMargin = -250;
                      view.setLayoutParams(layoutParams);
                      break;
              }
              rootlayout.invalidate();
              return true;
          }
      
      
      }
      

      【讨论】:

      • 谢谢奥马尔。我一直在尝试这种方法,但没有运气。不过,我有一些代码在工作,所以会在几秒钟内发布。还是谢谢。
      • 当我尝试这个时,我只在红框空间内得到了一个可移动的晶圆厂。 红框是虚构的 i.stack.imgur.com/a5o9j.png
      • @SubinBabu 我刚刚注意到您在两个不同的答案下发布了相同的评论。你能确认它适用于哪个答案吗?如果两者都适用,那么请查看我刚刚在上面的答案中留下的评论。另外,您能否确保您没有在我的解决方案中使用 Omar 的 Java 代码,因为这可能会破坏事情。干杯。
      【解决方案6】:

      实际上,您可以只使用 android.support.design.widget.CoordinatorLayout 而不是相对布局或任何其他布局,这将起作用(移动 FAB)

      【讨论】:

      • Hiya Rohit,您是否打算将其作为评论添加到现有答案而不是新答案? (在这种情况下,前者可能更合适。)
      【解决方案7】:

      这是为我工作的监听器,容差为 70。

      private class FloatingOnTouchListener implements View.OnTouchListener {
              private float x;
              private float y;
              private float nowX;
              private float nowY;
              private float downX;
              private float downY;
              private final int tolerance = 70;
      
              @Override
              public boolean onTouch(View view, MotionEvent event) {
                  if (event.getAction() == MotionEvent.ACTION_DOWN) {
                      x = (int) event.getRawX();
                      y = (int) event.getRawY();
                      downX = x;
                      downY = y;
                  } else
                  if (event.getAction() == MotionEvent.ACTION_MOVE) {
                      nowX = event.getRawX();
                      nowY = event.getRawY();
                      float movedX = nowX - x;
                      float movedY = nowY - y;
                      x = nowX;
                      y = nowY;
                      iconViewLayoutParams.x = iconViewLayoutParams.x + (int) movedX;
                      iconViewLayoutParams.y = iconViewLayoutParams.y + (int) movedY;
                      windowManager.updateViewLayout(view, iconViewLayoutParams);
                  } else
                  if (event.getAction() == MotionEvent.ACTION_UP) {
                      float dx = Math.abs(nowX - downX);
                      float dy = Math.abs(nowY - downY);
                      if (dx < tolerance && dy < tolerance) {
                          Log.d(TAG, "clicou");
                          Log.d(TAG, "dx " + dx);
                          Log.d(TAG, "dy " + dy);
                          windowManager.removeViewImmediate(iconView);
                          windowManager.addView(displayView, layoutParams);
                      } else {
                          Log.d(TAG, "dx " + dx);
                          Log.d(TAG, "dy " + dy);
                          return true;
                      }
                  }
                  return true;
              }
          }
      

      【讨论】:

        【解决方案8】:

        你可以试试这个代码 XML

         <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginEnd="8dp"
            android:layout_marginRight="8dp"
            android:id="@+id/dashboardShowActionsFab"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent" />
        

        JAVA

        fab.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View view, MotionEvent motionEvent) {
        
        
                    ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) view.getLayoutParams();
        
                    int action = motionEvent.getAction();
                    if (action == MotionEvent.ACTION_DOWN) {
        
                        downRawX = motionEvent.getRawX();
                        downRawY = motionEvent.getRawY();
                        dX = view.getX() - downRawX;
                        dY = view.getY() - downRawY;
        
                        return true; // Consumed
        
                    } else if (action == MotionEvent.ACTION_MOVE) {
        
                        int viewWidth = view.getWidth();
                        int viewHeight = view.getHeight();
        
                        View viewParent = (View) view.getParent();
                        int parentWidth = viewParent.getWidth();
                        int parentHeight = viewParent.getHeight();
        
                        float newX = motionEvent.getRawX() + dX;
                        newX = Math.max(layoutParams.leftMargin, newX); // Don't allow the FAB past the left hand side of the parent
                        newX = Math.min(parentWidth - viewWidth - layoutParams.rightMargin, newX); // Don't allow the FAB past the right hand side of the parent
        
                        float newY = motionEvent.getRawY() + dY;
                        newY = Math.max(layoutParams.topMargin, newY); // Don't allow the FAB past the top of the parent
                        newY = Math.min(parentHeight - viewHeight - layoutParams.bottomMargin, newY); // Don't allow the FAB past the bottom of the parent
        
                        view.animate()
                                .x(newX)
                                .y(newY)
                                .setDuration(0)
                                .start();
        
                        return true; // Consumed
        
                    } else if (action == MotionEvent.ACTION_UP) {
        
                        float upRawX = motionEvent.getRawX();
                        float upRawY = motionEvent.getRawY();
        
                        float upDX = upRawX - downRawX;
                        float upDY = upRawY - downRawY;
        
                        if (Math.abs(upDX) < CLICK_DRAG_TOLERANCE && Math.abs(upDY) < CLICK_DRAG_TOLERANCE) { // A click
                            // return performClick();
                            Toast.makeText(MainActivity.this, "clicked", Toast.LENGTH_SHORT).show();
        
                        } else { // A drag
                            return true; // Consumed
                        }
        
                    } else {
                        //return super.onTouchEvent(motionEvent);
                    }
        
                    return true;
                }
        

        【讨论】:

        • 晶圆厂将在屏幕上移动
        【解决方案9】:

        这是一个略微更新的版本。它正确地处理了涟漪效应,至少它对我有用。

        public MovableFloatingActionButton(Context context) {
            super(context);
            init();
        }
        
        public MovableFloatingActionButton(Context context, AttributeSet attrs) {
            super(context, attrs);
            init();
        }
        
        public MovableFloatingActionButton(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            init();
        }
        
        private void init() {
            setOnTouchListener(this);
        }
        
        @Override
        public boolean onTouch(View view, MotionEvent motionEvent){
            ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams)view.getLayoutParams();
        
            switch (motionEvent.getActionMasked()) {
                case MotionEvent.ACTION_DOWN:
                    downRawX = motionEvent.getRawX();
                    downRawY = motionEvent.getRawY();
                    dX = view.getX() - downRawX;
                    dY = view.getY() - downRawY;
                    return super.onTouchEvent(motionEvent);
        
                case MotionEvent.ACTION_MOVE:
                    int viewWidth = view.getWidth();
                    int viewHeight = view.getHeight();
        
                    View viewParent = (View)view.getParent();
                    int parentWidth = viewParent.getWidth();
                    int parentHeight = viewParent.getHeight();
        
                    float newX = motionEvent.getRawX() + dX;
                    newX = Math.max(layoutParams.leftMargin, newX);
                    newX = Math.min(parentWidth - viewWidth - layoutParams.rightMargin, newX);
        
                    float newY = motionEvent.getRawY() + dY;
                    newY = Math.max(layoutParams.topMargin, newY);
                    newY = Math.min(parentHeight - viewHeight - layoutParams.bottomMargin, newY);
        
                    view.animate().x(newX).y(newY).setDuration(0).start();
                    setPressed(false);
                    return true;
        
                case MotionEvent.ACTION_UP:
                    final float upRawX = motionEvent.getRawX();
                    final float upRawY = motionEvent.getRawY();
        
                    final float upDX = upRawX - downRawX;
                    final float upDY = upRawY - downRawY;
        
                    final boolean isDrag = Math.abs(upDX) >= CLICK_DRAG_TOLERANCE || Math.abs(upDY) >= CLICK_DRAG_TOLERANCE;
                    return isDrag || performClick();
        
                default:
                    return super.onTouchEvent(motionEvent);
        
            }
        }
        

        【讨论】:

        • Hiya Samuel,您能否添加解释以突出显示您为处理涟漪效应所做的更改?
        • 嘿,我实际上只为 MotionEvent.ACTION_DOWN 返回 super.onTouchEvent(motionEvent) (以启动波纹效果),并在 MotionEvent.ACTION_MOVE 上调用 setPressed(false) 以在移动按钮时取消按下按钮。我还认为我的版本在使用开关时更具可读性,但是这是非常主观的。玩得开心编程!
        • 我也想知道你是否有同样的涟漪效应问题?也许这取决于 Android 版本?
        • 我将您的两项更改添加到我的代码中,但 MFAB 将不再移动。另外,我测试了原始的 com.google.android.material.floatingactionbutton.FloatingActionButton,它似乎也没有任何连锁反应。
        • 我忘了提到我在我的 xml 中使用了 android:background="?android:attr/selectableItemBackground"。
        猜你喜欢
        • 2023-03-15
        • 1970-01-01
        • 2016-07-02
        • 2015-08-30
        • 2016-01-13
        • 2015-11-08
        • 1970-01-01
        相关资源
        最近更新 更多