【问题标题】:Create FloatingActionButton programmatically (without xml)以编程方式创建 FloatingActionButton(无 xml)
【发布时间】:2017-07-26 19:44:47
【问题描述】:

我很欣赏 Android 的 FloatingActionButton (fab) 功能,并希望在我的项目中的许多不同地方使用它们。

现在,我有这样的东西,我有几个xml规范,除了id、icon和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 设计视图之类的功能。所以工作起来要困难得多。

【问题讨论】:

  • 考虑在 xml 中创建您的样式,然后应用该样式或使用辅助类以避免代码重复
  • @ShreyashSSarnayak 好的,我查看了文档。我看到至少一个无法以编程方式设置的属性——即 fabSize。所以我想我要推断出真正的答案是“不,你不能”?
  • @Stefan 谢谢Stefan,你的回答更有帮助。
  • 您可以使用setSize 以编程方式设置大小,它不像您预期​​的那样命名为setfabSize

标签: android xml inheritance floating-action-button


【解决方案1】:

我能想到的有两个

仅使用 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

编辑:

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

把它附加到你的父母身上

layout.addView(v);

但我觉得使用LayoutInflater 更好,因为它同时完成了生成 FloatingActionButton 并将其附加到其父级的任务。

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

【讨论】:

  • 布局充气器不起作用,因为 FloatingActionButton 不是布局。
  • 我用布局充气机进行了测试,它工作正常。我放置了与您在问题中发布的完全相同的 xml(只有 FAB 没有布局)。
  • 以编程方式获取主题属性看起来并不容易。看到这个answer
  • 嗯,好的。好吧,当我尝试它时它不会编译,它只是说:预期的资源类型布局。如果我将定义工厂的 xml 移动到它自己的文件中,它仍然无法将其识别为布局。访问它的唯一方法是通过 R.id.fabFoo,没有称为 R.layout.fabFoo 的标识符
  • Layout 只不过是ViewGroup。因此,可以使用您拥有的任何布局(LinearLayout、RelativeLayout 等)。对要放置此 FAB 的布局执行 findViewById 并将其类型转换为 ViewGroup。示例 - vg = (ViewGroup) findViewById(...)
【解决方案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);
    }
}

现在

【讨论】:

    【解决方案3】:

    高级用户

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

    • 边距,
    • 填充,
    • 旋转
    • 约束集
    • 色调
    • 可绘制
    • 点击监听器

      private fun addFabButton() {
      
          // tint color from theme
          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()              // set ID
              scaleType = ImageView.ScaleType.FIT_XY  // scale Type
              setImageResource(R.drawable.ic_toolkit_arrow_left_auto_mirror) // UI LIb icon
              setColorFilter(tintColor) // tint color based on theme
      
              setOnClickListener { v: View ->
                 //Handle Click
              }
          }
      
          parentView.addView(pillView)
      
          // --------Set Height, Width & padding --------
          val params = pillView.layoutParams
      
           // convert dp to pixels
          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
          // --------Apply Constraint set-------
          val set = ConstraintSet()
          set.clone(view)
          // Left Constraint
          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
          )
          // top Constraint
          set.connect(pillView.id,ConstraintSet.TOP,ConstraintSet.PARENT_ID,ConstraintSet.TOP,0)
          set.applyTo(view)
      
      }
      

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-11-17
      • 2010-12-02
      • 1970-01-01
      • 1970-01-01
      • 2013-03-28
      • 2013-07-25
      • 2013-07-22
      相关资源
      最近更新 更多