gpt4 book ai didi

Android Spinner 显示动画 Material 设计

转载 作者:IT老高 更新时间:2023-10-28 23:01:02 25 4
gpt4 key购买 nike

我只需要一些非常简单的东西。在网上找不到任何可以帮助我实现 following behaviour 的指南/资源:

所以有3件事:

  1. 似乎与 View 绑定(bind)的涟漪
  2. 放大弹窗动画(找不到自定义方法)
  3. 文本从 Spinner 字段转移到实际弹出窗口

感谢任何帮助。

编辑

涟漪实际上是可以在文档中找到的直截了当的东西。弹出下拉菜单的放大动画是我最感兴趣的。如果我只能获得对该弹出窗口的引用,我可以为它制作任何我想要的动画......任何人的想法?

最佳答案

在过去 >48 小时内,我一直在努力解决这个问题(我有一些额外的时间不要怪我),我可以肯定地告诉你这些:

  1. 使用 AppCompat 主题和普通 Spinner 为您提供免费的涟漪(耶!)。如果你有一个自定义的 Spinner 确保扩展 AppCompatSpinner ,你会得到一些好的主题。引用 AppCompatSpinner javadoc:

A Spinner which supports compatible features on older version of the platform, including:

  • Allows dynamic tint of it background via the background tint methods in ViewCompat.
  • Allows setting of the background tint using backgroundTint and backgroundTintMode.
  • Allows setting of the popups theme using popupTheme.

This will automatically be used when you use Spinner in your layouts. You should only need to manually use this class when writing custom views.

  1. 没有没有方法来检索通过扩展ANY类显示的PopupWindow。有很多嵌套类有助于该功能(剧透:它们大多是私有(private)的)。

  2. 可以在您的主题中自定义 PopupWindow...静态 的进入和退出过渡(哇哦!)。我目前正在使用 AppCompat v23 并进行了一些调查,发现:

    • 自定义ListPopupWindowLOLLIPOP及以上的样式

      <style name="Widget.Material.ListPopupWindow">
      <item name="dropDownSelector">?attr/listChoiceBackgroundIndicator</item>
      <item name="popupBackground">@drawable/popup_background_material</item>
      <item name="popupElevation">@dimen/floating_window_z</item>
      <item name="popupAnimationStyle">@empty</item>
      <item name="popupEnterTransition">@transition/popup_window_enter</item>
      <item name="popupExitTransition">@transition/popup_window_exit</item>
      <item name="dropDownVerticalOffset">0dip</item>
      <item name="dropDownHorizontalOffset">0dip</item>
      <item name="dropDownWidth">wrap_content</item>
      </style>
    • 在 LOLLIPOP 之前对其进行自定义的样式:

      <style name="Base.Widget.AppCompat.ListPopupWindow" parent="">
      <item name="android:dropDownSelector">?attr/listChoiceBackgroundIndicator</item>
      <item name="android:popupBackground">@drawable/abc_popup_background_mtrl_mult</item>
      <item name="android:dropDownVerticalOffset">0dip</item>
      <item name="android:dropDownHorizontalOffset">0dip</item>
      <item name="android:dropDownWidth">wrap_content</item>
      </style>
    • 这就是您在主题中设置的内容:

      // From the constructor listPopupWindowStyle is the 
      // theme attribute you're looking for.
      public ListPopupWindow(Context context, AttributeSet attrs) {
      this(context, attrs, R.attr.listPopupWindowStyle);
      }

也就是说,我仍在获取您的详细信息,但我正在通过 克隆 2 个类来解决它:AppCompatSpinnerListPopupWindow 并将公共(public) getPopup() getter 添加到克隆的 ListPopupWindow 代码中,以便在我的克隆 AppCompatSpinner 中访问它。这带来了几个机会。一个例子是我的 centerPopup() 方法,它应该根据 spinnerItem(在微调器 View 本身中显示的选定项目)和 spinnerDropdownItem(单个 View )的中心移动布局弹出窗口的位置在下拉列表中显示为列表项)。然后在调用 super.show()

之后立即在 DropdownPopup.show() 中调用 centerPopup() 方法
private void centerPopup(boolean updateListSelection) {
boolean aboveAnchor = getPopup().isAboveAnchor();

int[] spinnerLocation = new int[2];
int[] popupLocation = new int[2];

ListView listView = getListView();

/*
Popup is anchored at spinner TOP LEFT when it is set to overlap else at BOTTOM LEFT

Also seems the windowlayoutparams generated for popup is wrapcontent for width and height
As a result popup locationOnScreen returns [0, 0] which is relative to the window.
We can take it as relative to spinner location and add spinnerLocation X value to give
left edge of popup
*/

MaterialSpinner.this.getLocationInWindow(spinnerLocation);
int spMidX = spinnerLocation[0] + (MaterialSpinner.this.getWidth() / 2);
int spMidY = spinnerLocation[1] + (MaterialSpinner.this.getHeight() / 2);

Rect spinnerBgdPadding = new Rect();
MaterialSpinner.this.getBackground().getPadding(spinnerBgdPadding);

// ----- BUG - returns erroneous height
// Ideally should measure one of the drop down list children and give a height
// exactly as it wouldwhen laid out eventually.
// Works only for lists with homogenously tall content
View child = listView.getAdapter().getView(0, null, listView);

child.setLayoutParams(new LayoutParams(WRAP_CONTENT, WRAP_CONTENT));

child.measure(
MeasureSpec.makeMeasureSpec(listView.getWidth() - listView.getPaddingLeft() - listView.getPaddingRight(), MeasureSpec.AT_MOST),
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)
);
int listItemHeight = child.getMeasuredHeight();
// ----- /BUG

getPopup().getContentView().getLocationInWindow(popupLocation);
int popMidX = spinnerLocation[0] + (getPopup().getWidth()) / 2;
int popMidY = spinnerLocation[1] + (listItemHeight / 2);

int hoff = getHorizontalOffset();
int voff = getVerticalOffset();

int xoff = spMidX - popMidX - hoff - spinnerBgdPadding.left;
int yoff = spMidY - popMidY - voff;

getPopup().update(spinnerLocation[0] + xoff, spinnerLocation[1] + yoff, -1, -1, true);

if (updateListSelection)
listView.setSelectionFromTop(MaterialSpinner.this.getSelectedItemPosition(), 0)
;

// getPopup().update(MaterialSpinner.this, xoff, yoff, -1, -1);
// int numVisItems = listView.getLastVisiblePosition() - getFirstVisiblePosition();

}

如果返回了正确的 listItemHeight,弹出窗口不仅应该出现在微调器上,而且文本中心也应该对齐。 (由于背景和填充相关问题,可能会偏离一些像素,但可以解决)。

一旦居中,下一步就是将 dropDownList selectedPosition View 滚动到 popupWindow 的中心并更新 yoff Y-相应地偏移。

popupEnterTransition 属性仅限于 LOLLIPOP 但如果这不是问题,您可以在此处插入放大转换,这应该可以获得您想要的效果。不过我还没有尝试过,但我也认为更好的动画应该是微调器中心的显示效果(看起来像你的规范视频中的那个)。

但所有这些都很好...理论上 x_x 哈哈

关于Android Spinner 显示动画 Material 设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30053820/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com