简体   繁体   English

Android:TextView.setLayoutParams有时可以工作,有时则不行

[英]Android: TextView.setLayoutParams sometimes work, sometimes doesn't

I have an android app that let's the user modify some layout parameters. 我有一个Android应用程序,让用户修改一些布局参数。 One of my functions let's the user decide if a TextView will be aligned against the top or the bottom of a picture. 我的功能之一是让用户决定TextView是与图片的顶部还是底部对齐。

This is the function: 这是功能:

private void setAlign(String align) {

    /* Get Preferences */
    SharedPreferences prefs = getSharedPreferences("prefs", Context.MODE_WORLD_READABLE);
    SharedPreferences.Editor editor = prefs.edit();

    editor.putString("align", align);
    editor.commit();

    Log.d("ALIGN", align);

    paramAlign = align;

    FrameLayout.LayoutParams floLP = new FrameLayout.LayoutParams(
                                            FrameLayout.LayoutParams.WRAP_CONTENT,
                                            FrameLayout.LayoutParams.WRAP_CONTENT,
                                            (align == "TOP") ? Gravity.TOP : Gravity.BOTTOM);

    txtGoal.setLayoutParams(floLP);

    int res = paramAlign == "TOP" ? R.drawable.btn_toolbar_align_top_up : R.drawable.btn_toolbar_align_bottom_up ;
    btnAlign.setImageResource(res);

}

Now once the activity is started, this function works fine. 现在,一旦开始活动,此功能就可以正常工作。 However, when I initialize the activity, I call the setAlign() function in the onGlobalLayout method after retrieving the alignment preference. 但是,当我初始化活动时,我在获取对齐方式首选项后在onGlobalLayout方法中调用setAlign()函数。

This is the relevant code: 这是相关代码:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.personalize);

    /* Get Preferences */
    SharedPreferences prefs = getSharedPreferences("prefs", Context.MODE_WORLD_READABLE);

    paramAlign = prefs.getString("align", "BOTTOM");

    Log.d("ALIGN", paramAlign);

    // Get screen dimensions and initialize preview
    ViewTreeObserver vto = rootView.getViewTreeObserver();
    vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {

        @Override
        public void onGlobalLayout() {

        setAlign(paramAlign);

        ViewTreeObserver obs = rootView.getViewTreeObserver();
            obs.removeGlobalOnLayoutListener(this);
        }

    });

}

Now if you notice the logging functions, they both return "TOP" when I start the activity. 现在,如果您注意到日志记录功能,则在我开始活动时它们都将返回“ TOP”。 And the setAlign() function is obviously getting called. 并且setAlign()函数显然被调用。 Yet, the TextView is aligned at the bottom. 但是,TextView在底部对齐。 This is the XML for the TextView: 这是TextView的XML:

<TextView
                android:id="@+id/txtGoal"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:padding="10dip"
                android:textColor="@color/color_white"
                android:textSize="8sp"
                android:shadowColor="@color/color_black"
                android:shadowDx="1.2"
                android:shadowDy="1.2"
                android:shadowRadius="1.2"
                />

Any idea why the setLayoutParams is not happening when the activity is created? 知道为什么创建活动时未发生setLayoutParams吗? The function is getting fired when the layout is done being drawn so it shouldn't be the issue here. 绘制完布局后,该函数将被触发,因此这里不应该成为问题。 And the XML has no gravity specified to start with. 而且XML没有指定开始的重力。

What am I missing here? 我在这里想念什么?

First of all, I see that the variable txtGoal is not initialized (nor even declared) so I am assuming you did that somewhere else (that is not posted in the question). 首先,我看到变量txtGoal没有初始化(甚至没有声明),所以我假设您在其他地方做了(这没有在问题中发布)。

The behavior you are encountering is pretty much normal : the function is working only at start-up, and that's because once you change the layout of your text view, you must indicate that so it will be redrawn, by adding the following : 您遇到的行为几乎是正常的:该功能仅在启动时才起作用,这是因为一旦更改了文本视图的布局,您必须通过添加以下内容来表示将其重绘:

txtGoal.invalidate ();

after this : 在这之后 :

txtGoal.setLayoutParams(floLP);

EDIT: 编辑:

You can also try changing the gravity in a different way: 您还可以尝试以其他方式更改重力:

 
 
 
  
  txtGoal.setGravity ( Gravity.TOP );
 
  


EDIT: 编辑:

My apologies, what I suggest (the second solution) is wrong, because it changes the gravity of the text inside the text view (and not the gravity of the text view inside the root view). 我的道歉,我的建议(第二个解决方案)是错误的,因为它改变了文本视图内文本的重力(而不是根视图内文本视图的重力)。

Please try the following: 请尝试以下操作:

Do not try to modify the gravity of your text view using a listener, you can directly apply the gravity you want after setting the content view of your activity (because the text view is thus created). 请勿尝试使用侦听器修改文本视图的重力,而是可以在设置活动的内容视图后直接应用所需的重力(因为这样便创建了文本视图)。 I advise the following: 我建议以下几点:

Apply the new layout to your text view directly (not via the listener) after retrieving the shared preferences. 检索共享的首选项后,将新布局直接应用于文本视图(而不是通过侦听器)。

Your onCreate method should look something similar to this: 您的onCreate方法应类似于以下内容:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.personalize);

    /* Get Preferences */
    SharedPreferences prefs = getSharedPreferences("prefs", Context.MODE_WORLD_READABLE);

    paramAlign = prefs.getString("align", "BOTTOM");

    setAlign(paramAlign);

}

You should compare two string using the equals method: 您应该使用equals方法比较两个字符串:

Replace that : 替换为:

(align == "TOP")

By that 通过那个

align.equals ( "TOP" )

And this : 和这个 :

paramAlign == "TOP"

By this : 这样 :

paramAlign.equals ( "TOP" )

So, here is what I found out and what I did to fix my problem. 因此,这就是我发现的问题以及为解决问题所做的事情。

Apparently the condition 显然情况

align == "TOP"

Was not testing true when the activity was started altho the Log dump would tell me that it was in fact true at the time. 当活动开始时,如果没有测试正确,日志转储会告诉我实际上当时是正确的。 Now why it did that I have no clue. 现在为什么这样做,我一无所知。 This seems like a weird bug. 这似乎是一个奇怪的错误。 That condition tested true once the activity was running. 活动运行后,该条件即为真。

Since this parameter could only have 2 values, I switched it to a Boolean variable where false is now the equivalent of "BOTTOM" and true the equivalent of "TOP" and it is working perfectly. 由于该参数只能有2个值,我把它切换到一个布尔变量,其中虚假现在是“底”和“顶”的真实等同等效,它是可以正常使用。

This is something that might actually need to be looked into as the condition should of tested true at startup. 由于在启动时必须对条件进行测试,因此实际上可能需要对此进行检查。

** EDIT ** **编辑**

You cannot compare 2 strings in java using the "==" operator. 您不能使用“ ==”运算符在Java中比较2个字符串。 You have to use .equals() instead. 您必须改用.equals()。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM