【问题标题】:Margin on custom TextView自定义 TextView 的边距
【发布时间】:2013-07-19 06:39:49
【问题描述】:

我检查了很多答案,但到目前为止都没有帮助。

我正在尝试扩展 android 的 TextView 并在代码中设置此自定义视图的边距,因为我将在按钮按下和类似的事情上实例化它们。它被添加到一个线性布局。这就是我得到的:

public class ResultsView extends TextView {
    public ResultsView(Context context) {
        super(context);
        LinearLayout.LayoutParams layout = new LinearLayout.LayoutParams(
            ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        layout.setMargins(15, 15, 15, 15);
        setLayoutParams(layout);
    }
}

任何地方都没有边距迹象。

编辑:我可能想补充一下,如果我在 xml 中分配一个边距值,它确实有效。

【问题讨论】:

    标签: android textview margin


    【解决方案1】:

    正如@MartinCazares 指出的那样,问题在于布局参数在构造函数方法中不可用,并且将在视图膨胀期间被覆盖。但是,最好在 setLayoutParams() 中设置边距,这将在 View 膨胀期间调用,而不是在 onLayout() 中。后者应该设置视图子项的布局,而不是更改视图本身的布局。因此,在我的 Android 12 上更改布局参数会导致屏幕闪烁。

    我的解决方案:

    private boolean hasLeftMargin = false;
    private boolean hasRightMargin = false;
    private boolean hasTopMargin = false;
    private boolean hasBottomMargin = false;
    
    public MyView(@NonNull Context context, @Nullable AttributeSet attrs) {
        // Receive styled attributes
        TypedArray arr = context.obtainStyledAttributes(attrs, new int[] {
                android.R.attr.layout_margin,
                android.R.attr.layout_marginLeft, android.R.attr.layout_marginTop,
                android.R.attr.layout_marginRight, android.R.attr.layout_marginBottom,
                android.R.attr.layout_marginStart, android.R.attr.layout_marginEnd});
    
        // Check whether margin are assigned in xml (by index of int array above)
        hasLeftMargin = arr.hasValue(0) || arr.hasValue(1) || arr.hasValue(5);
        hasRightMargin = arr.hasValue(0) || arr.hasValue(3) || arr.hasValue(6);
        hasTopMargin = arr.hasValue(0) || arr.hasValue(2);
        hasBottomMargin = arr.hasValue(0) || arr.hasValue(4);
        arr.recycle();
    }
    
    @Override
    public void setLayoutParams(ViewGroup.LayoutParams params) {
        if (params instanceof MarginLayoutParams) {
            MarginLayoutParams p = (MarginLayoutParams) params;
            if (!hasLeftMargin && p.leftMargin <= 0) p.leftMargin = sideMargin;
            if (!hasRightMargin && p.rightMargin <= 0) p.rightMargin = sideMargin;
            if (!hasTopMargin && p.topMargin <= 0) p.topMargin = verticalMargin;
            if (!hasBottomMargin && p.bottomMargin <= 0) p.bottomMargin = verticalMargin;
        }
        super.setLayoutParams(params);
    }
    

    【讨论】:

      【解决方案2】:

      我认为问题是,当您尝试添加边距时,layoutparams 尚未设置,为什么不尝试在 ResultsView 类中覆盖此方法:

             protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
                  MarginLayoutParams margins = MarginLayoutParams.class.cast(getLayoutParams());
                  int margin = 15;
                  margins.topMargin = margin;
                  margins.bottomMargin = margin;
                  margins.leftMargin = margin;
                  margins.rightMargin = margin;
                  setLayoutParams(margins);
              };
      

      并删除您在构造函数中的代码,这样会应用边距,直到我们确定我们有视图的布局对象,希望这会有所帮助

      问候!

      【讨论】:

      • 耶!真的做到了,谢谢!我之前实际上尝试过类似的东西,但是使用了 onFinishInflate,它不起作用。你知道这在性能方面有多好吗?我是否应该添加一个布尔值来检查我们是否已经设置过一次?
      • 我不认为这是一个巨大的性能影响,但如果你担心它,你可以添加标志只做一次如果你愿意...
      • 我认为您可能只需修改传递给 onLayout() 的尺寸(例如 left += leftMargin, right -= rightMargin, top += topMargin, bottom -= bottomMargin, super.onLayout (改变,左,上,右,下));
      • 不适用于线性布局。可能是因为你从未调用过 super.onLayout
      • @MartinCazares 嗨,我的边距为空...有什么建议吗?
      【解决方案3】:

      您现在需要将此视图添加到当前正在显示的布局中。你错过了下一步。 所以现在你需要这样的东西:

          currentlayout.addview(View);
      

      【讨论】:

      • 它是在 XML 中添加的。我可以在我的 LinearLayout 中看到文本视图,但它们没有边距。
      猜你喜欢
      • 1970-01-01
      • 2012-11-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多