【问题标题】:Android programmatically added views not showing in UIAndroid 以编程方式添加的视图未在 UI 中显示
【发布时间】:2019-11-11 16:22:46
【问题描述】:

我对 Java/Android 非常陌生,可能会在我能走路之前尝试跑步,但我从旧的“Mastermind”代码猜谜游戏的版本开始取得了一些成功。我目前的绊脚石是,在输入了我对代码的第一个猜测并生成了这个猜测的分数后,我想呈现一排新的“洞”准备接受我的下一个猜测(第一组洞在我的 @ 987654321@ 文件)。我有一个名为guesses 的LinearLayout(垂直方向)来保存孔的行,每行孔都是一个包含TextView 的LinearLayout(水平方向),以指示这是哪个猜测数字,以及用于空猜洞和得分洞。

我已经编写了代码来获取guesses 布局作为父布局,创建一个新的水平线性布局并使用addView 将其添加到guesses 布局中。然后,我切换我的“父”布局以指向我刚刚创建的新水平 LinearLayout,并创建各种其他 TextView 和 ImageView 项目并将它们添加到这个新的水平 LinearLayout。

此代码全部运行,没有任何错误。我只是在 UI 中看不到我的任何新布局。我错过了什么?

到目前为止的代码摘录:

parentLayout = (LinearLayout)findViewById(R.id.guesses);
LinearLayout guessLayout = new LinearLayout(MainActivity.this);
guessLayout.setOrientation(LinearLayout.HORIZONTAL);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
                        getResources().getIdentifier("@dimens/guessLayoutHeight", null, getPackageName()));
int pxMargin = (int) TypedValue.applyDimension(
                        TypedValue.COMPLEX_UNIT_DIP,
                        getResources().getIdentifier("@dimens/guessLayoutMargin", null, getPackageName()),
                        getResources().getDisplayMetrics());
layoutParams.setMargins(pxMargin, 0, pxMargin, 0);
guessLayout.setLayoutParams(layoutParams);
guessLayout.setId(guessNumber*10);
parentLayout.addView(guessLayout);

// Add the Guess# label
parentLayout = (LinearLayout)findViewById(guessNumber*10);
TextView guessLabel = new TextView(MainActivity.this);
layoutParams = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 11);
layoutParams.gravity = Gravity.CENTER_VERTICAL;
guessLabel.setText("Guess " + guessNumber);
guessLabel.setLayoutParams(layoutParams);
guessLabel.setId(guessNumber*100);
parentLayout.addView(guessLabel);

// Add the guess positions
ImageView guessPosition;
pxMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20, getResources().getDisplayMetrics());
for (int i = 1 ; i <=4 ; i++ ) {
    guessPosition = new ImageView(MainActivity.this);
    layoutParams = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 6);
    if (i == 1) {
        layoutParams.setMarginStart(pxMargin);
    } else {
        layoutParams.setMarginStart(0);
    }
    guessPosition.setLayoutParams(layoutParams);
    guessPosition.setId(guessNumber*10 + i);

    guessPosition.setImageResource(getResources().getIdentifier("@drawable/blank_guess", null, getPackageName()));
    guessPosition.setTag("blank_guess");
    guessPosition.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
    parentLayout.addView(guessPosition);
}

[编辑 - 可以忽略以下附加问题。已经回答] 此代码位于我的 Score 按钮的 onClickListener 中。我想做的另一件事是,为我的猜测漏洞创建了新的 ImageView 项目,调用setOnDragListener 以使用我在MainActivity.java 的封闭onCreate 方法中定义的侦听器。是否可以从另一个侦听器的代码中引用此侦听器?我在类级别有以下声明:

ImageView guess1 = null;

...而我希望做的是类似

guess1 = findViewById(guessNumber*10 + 1);
guess1.setOnDragListener(MainActivity.this.guessDragListener);

但它告诉我它无法解析符号 guessDragListener

【问题讨论】:

    标签: android android-layout


    【解决方案1】:

    关于您的第二个问题:我不确定我是否理解正确。您想对多个视图使用相同的 OnDragListener 吗?如果是这样,试试这个:

    View view = findViewById(R.id.view);
    View view2 = findViewById(R.id.view2);
    View.OnDragListener onDragListener;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
         onDragListener = new View.OnDragListener() {
            @Override
            public boolean onDrag(View v, DragEvent event) {
                return false;
            }
        };
    
        view.setOnDragListener(onDragListener);
        doStuff();
    }
    
    void doStuff(){
        view2.setOnDragListener(onDragListener);
    }
    

    【讨论】:

    • 谢谢。我需要的是将监听器的声明移到 Class 级别,而不是在 onCreate() 中。
    • 对于您的其他问题,请查看“布局检查器”。它在“工具”下。也许视图会显示在那里。
    • 酷!所以对于原始对象(在activity_main.xml 中定义),它们显示为AppCompatTextViewAppCompatImageView,而我以编程方式添加的对象显示为TextViewImageView。所以他们那里,我只是在 UI 中看不到他们。我是否必须做一些事情来刷新屏幕才能显示这些新对象?还是我需要将它们添加为 AppCompat... 版本(如果是,那么如何)?
    • 使用 Layout Inspector 后,我发现这与我如何转换各种尺寸的单位有关 - 我使用 pxMargin = ...。在我的dimens.xml 中,所有内容都在 dp 中定义,但我认为所有设置高度、边距等的方法都需要像素,所以我需要转换。我尝试将新对象的尺寸硬编码为与原始静态对象相同的尺寸,并且奇迹般地开始出现。我现在必须弄清楚如何正确地进行从 dp 到 px 的转换。
    • 我正在使用这个: int i = Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, value, context.getResources().getDisplayMetrics()));您可能不需要 Math.round,如果您想反之亦然,我认为您甚至可以将 COMPLEX_UNIT_DIP 与 COMPLEX_UNIT_PX 交换。
    【解决方案2】:

    您正在添加相同的视图 4 次。该变量未重新创建,但正在更改其引用

    for (int i = 1 ; i <=4 ; i++ )
    ImageView guessPosition = new ImageView(MainActivity.this)
    ...
    

    而且整个边距可以减少到

    int margin = getResources().getDimens(R.dimens.name)
    

    该值在所需的 DP 上

    【讨论】:

    • 添加相同的视图 4 次 - 是的,那是因为我想要其中的 4 个。不过,感谢您提供有关 R.dimen.name 的指针 - 这使我的代码稍微整理了一下。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-25
    相关资源
    最近更新 更多