以编程方式创建FloatingActionButton(无需xml)

7

我很喜欢Android的FloatingActionButton(fab)功能,并希望在我的项目中使用它们。

目前,我有类似下面这样的内容,我为它们编写了几个xml规范,它们都是相同的,除了id、图标和onclick不同。

<android.support.design.widget.FloatingActionButton
    android:id="@+id/fabFoo"
    android:onClick="onFabFoo"
    android:src="@drawable/ic_foo" 
    app:backgroundTint="?attr/colorButtonNormal"
    app2:elevation="2dp"
    app:fabSize="mini" 
    android:focusable="true"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_alignParentLeft="true"
    android:layout_margin="2dp"
    app:rippleColor="?attr/colorSwitchThumbNormal" />

为了避免重复的代码...有没有一种方式可以完全以编程方式创建fab,而不需要在xml中指定它?
...
尝试一些建议... 直到我将SDK升级到当前版本(#25),才有了“setSize”。
FloatingActionButton fab = new FloatingActionButton(this);
fab.setId(View.generateViewId());
fab.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View v) {
      Log.d("DEBUG", "onFabFoo");
   }
});
fab.setImageResource(R.drawable.ic_foo);
fab.setElevation(2);
fab.setSize(android.support.design.widget.FloatingActionButton.SIZE_MINI);
fab.setFocusable(true);
RelativeLayout.LayoutParams lay = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
                        ViewGroup.LayoutParams.WRAP_CONTENT);
lay.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
lay.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
lay.setMargins(2,2,2,2);
fab.setLayoutParams(lay);

我还没有弄清楚如何设置颜色。

//  app:backgroundTint="?attr/colorButtonNormal"
//  app:rippleColor="?attr/colorSwitchThumbNormal"

我看到有设置这些(setBackgroundTintList和setRippleColor)的方法,但我不知道如何将其设置为我在原始xml设置中选择的颜色(colorButtonNormal和colorSwitchThumbNormal)。
此外,我不知道如何将其附加到父级并使其显示...
好吧,我现在明白了,如果您全部以编程方式进行,则无法使用Android Studio中的xml设计视图等功能。因此,它要处理起来更加困难。

2
这一切都在文档里。 - Shreyash S Sarnayak
1
考虑使用 XML 来定义样式,然后应用该样式或使用辅助类来避免代码重复。 - Stefan
@ShreyashSSarnayak 好的,我看了文档。我发现至少有一个属性无法通过编程设置 - 那就是fabSize。所以我猜我可以得出真正的答案是“不行,你不能”? - slashdottir
@Stefan 感谢你,你的回答更有帮助。 - slashdottir
2
您可以使用 setSize 以编程方式设置大小,它的名称不是您预期的 setfabSize - Shreyash S Sarnayak
显示剩余2条评论
3个回答

6

我可以想到两种方法

仅使用Java

像下面这样直接在代码中创建一个FloatingActionButton

public FloatingActionButton getFab(Context context) {
    FloatingActionButton fab = new FloatingActionButton(context);
    ...
    return fab;
}

填充布局

public FloatingActionButton getFab(Context context, ViewGroup parent) {
    LayoutInflater inflater = LayoutInflater.from(context);
    return (FloatingActionButton) inflater.inflate(R.layout.myfab, parent, false);
}

更多关于 inflater 的信息请参考 inflate

编辑:

你可以使用 setBackgroundTintListsetRippleColor 来设置这两个属性。

要将其附加到父级,请执行以下操作

layout.addView(v);

但是我认为使用LayoutInflater更好,因为它可以同时生成一个FloatingActionButton并将其附加到其父级。

inflater.inflate(R.layout.myfab, layout, true)

布局填充器不起作用,因为FloatingActionButton不是一个布局。 - slashdottir
我使用布局填充器进行了测试,它可以正常工作。我将与您在问题中发布的完全相同的 XML(仅包含 FAB,没有布局)放置在了其中。 - Shreyash S Sarnayak
嗨。好的。顺便说一下,我觉得在名字fabFoo.xml中使用大写字母是不被允许的。 - Shreyash S Sarnayak
2
Layout is nothing but a ViewGroup. So whichever layout you have (LinearLayout, RelativeLayout, etc.) can be used. Do findViewById of the layout in which you want to put this FAB and type cast it to ViewGroup. Example - vg = (ViewGroup) findViewById(...) - Shreyash S Sarnayak
你已经超出了帮助我的范围。谢谢! - slashdottir
显示剩余4条评论

2
我们可以通过编程实现创建一个浮动操作按钮。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/my_relative_layout">
</RelativeLayout>

这是主要的XML布局文件。 在这个父布局文件中,我们可以使用以下代码在类文件中创建浮动操作按钮。

public class MyClass extends AppCompatActivity{
    RelativeLayout relativeLayout;

    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_name);

        relativeLayout = (RelativeLayout) findViewByID(R.id.my_relative_layout);

        FloatingActionButton fab = new FloatingActionButton(getContext());
        fab.setId(R.id.fab_location_main);
        fab.setLayoutParams(new RelativeLayout.LayoutParams(
                RelativeLayout.LayoutParams.WRAP_CONTENT,
                RelativeLayout.LayoutParams.WRAP_CONTENT
                ));
        relativeLayout.addView(fab);
    }
}

现在

0

高级用户

如果您想更多地控制浮动操作按钮:

  • 边距(Margin)
  • 填充(Padding)
  • 旋转(Rotation)
  • 约束集(Constraint set)
  • 色调(Tint)
  • 可绘制对象(Drawable)
  • 点击监听器(Click listener)

    private fun addFabButton() {
    
        // 从主题获取色调颜色
        val typedValue = TypedValue()
        context.theme.resolveAttribute(R.attr.drawer_fab_tint, typedValue, true)
        @ColorInt val tintColor = typedValue.data
    
        val pillView = FloatingActionButton(context)
        pillView.run {
            id = View.generateViewId()              // 设置 ID
            scaleType = ImageView.ScaleType.FIT_XY  // 缩放类型
            setImageResource(R.drawable.ic_toolkit_arrow_left_auto_mirror) // UI 库图标
            setColorFilter(tintColor) // 根据主题的色调对图标进行着色
    
            setOnClickListener { v: View ->
               // 处理点击事件
            }
        }
    
        parentView.addView(pillView)
    
        // --------设置高度、宽度和填充--------
        val params = pillView.layoutParams
    
         // 将 dp 转换为像素
        params.height = context.resources.getDimensionPixelSize(R.dimen.fab_icon_height)
        params.width = context.resources.getDimensionPixelSize(R.dimen.fab_icon_width)
        pillView.layoutParams = params
    
        val padding = context.resources.getDimensionPixelSize(com.bmwgroup.idnext.keyboard.R.dimen.hide_key_padding)
        pillView.setPadding(padding,padding,padding,padding)
        pillView.requestLayout()
    
        pillView.rotation = -90f
        // --------应用约束集-------
        val set = ConstraintSet()
        set.clone(view)
        // 左侧约束
        val marginStart = context.resources.getDimensionPixelSize(com.bmwgroup.idnext.keyboard.R.dimen.hide_key_margin_start)
        set.connect(pillView.id,ConstraintSet.LEFT,ConstraintSet.PARENT_ID,ConstraintSet.LEFT,
                marginStart
        )
        // 顶部约束
        set.connect(pillView.id,ConstraintSet.TOP,ConstraintSet.PARENT_ID,ConstraintSet.TOP,0)
        set.applyTo(view)
    
    }
    

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接