Reputation: 2772
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?
Update: I Changed my code as following as you guys have suggested, and my TextView
still does not appear....
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);
}
}
Update: 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.
Update: Fixed it simply by changing calling super.onMeasure on 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.
Upvotes: 0
Views: 120
Reputation: 1765
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);
}
}
Upvotes: 2
Reputation: 23483
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);
}
Upvotes: 0