简体   繁体   中英

TextView not appearing when programatically adding it to a LinearLayout

Basically as the title says. I have a class that extends LinearLayout and I want that LinearLayout to have a child TextView inside. The problem is, the TextView does not seem to appear.

Here is what I have so far, what exactly am I doing wrong?

: I Changed my code as following as you guys have suggested, and my TextView still does not appear.... :我按照你们的建议更改了代码,如下所示,但我的TextView仍然没有出现。

public class CalendarCourseView extends LinearLayout {

    private int height;
    private int topMargin;
    private Course course;

    public CalendarCourseView(Context context, Course course, int topMargin,
                              int height) {
        super(context);
        final DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics();
        this.topMargin = (int) TypedValue
                .applyDimension(TypedValue.COMPLEX_UNIT_DIP, topMargin, displayMetrics);
        this.height = (int) TypedValue
                .applyDimension(TypedValue.COMPLEX_UNIT_DIP, height, displayMetrics);
        this.course = course;
        this.setBackgroundColor(course.getColor());
        setTextView();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), this.height);
        ((MarginLayoutParams) getLayoutParams()).topMargin = topMargin;
    }

    private void setTextView() {
        TextView textView = new TextView(this.getContext());
        LayoutParams params = new LayoutParams(new LinearLayout.LayoutParams(ViewGroup
                .LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        textView.setLayoutParams(params);
        textView.setText(course.getName());
        this.addView(textView);
    }

}

I pinned-point the problem. 我查明了问题所在。 It is with onMeasure. I believe the TextView is not placed in the same position as the LinearLayout after height and topMargin change.

Fixed it simply by changing calling super.onMeasure on onMeasure. 只需通过在onMeasure上调用super.onMeasure即可解决此问题。

 @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, this.height);
        ((MarginLayoutParams) getLayoutParams()).topMargin = topMargin;
    }

I believe it is because setMeasuredDimension(int, int) only changes the dimension of the View and not the children. I would also have had to override onLayout . Calling the super.onMeasure also changes the children and simplified things.

Check your code to see if

course.getName()

has a value. Just for testing purposes, you can say

textView.setText("MyCourseName");

for example.

This example below is working correctly for me.

public class CustomView extends LinearLayout {

    public CustomView(Context context) {
        super(context);
        Log.d("CusotmView", "on constructor after super(context)");

        TextView textView = new TextView(this.getContext());
        LayoutParams params = new LayoutParams(new LinearLayout.LayoutParams(ViewGroup
                .LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        textView.setLayoutParams(params);
        textView.setText("MyText");
        this.addView(textView);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        Log.d("CustomView", "onMeasure");
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
}

As it's been mentioned, calling setTextView from the onMeasure method is a bad idea. onMeasure is not always called consistentyly, like onCreate or onStart . On top of that, I don't think that you are properly adding the textView to the main view. I would put the setTextView inside the constructor like so:

public MyView(Context context, Course course, int topMargin,
                              int height) {
        super(context);
        final DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics();
        this.topMargin = (int) TypedValue
                .applyDimension(TypedValue.COMPLEX_UNIT_DIP, topMargin, displayMetrics);
        this.height = (int) TypedValue
                .applyDimension(TypedValue.COMPLEX_UNIT_DIP, height, displayMetrics);
        this.course = course;
        super.setBackgroundColor(course.getColor());
        this.setTextView();
    }

I will also add that you aren't adding the TextView to the correct view. You are adding it to the super class, rather than the view that has been created. You are going to need to get a reference to the view you are trying to add the layout to. Maybe it would look something like this:

private void setTextView() {
        TextView textView = new ResponsiveTextView(super.getContext());
        LayoutParams params = new LayoutParams(new LinearLayout.LayoutParams(ViewGroup
                .LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        textView.setLayoutParams(params);
        textView.setText(course.getName());
        //You should reference the object being created rather than the super class
        this.addView(textView);

    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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