I'm building a custom view, sort of like a custom bar chart. I'm extending the LinearLayout
for this one. The custom view then populates the views from data. Problem is, whenever I want the views to be 'refreshed', I am calling removeAllViews()
and similar methods, so the custom view layout is in clean slate, then to repopulate the data, I call addView()
, but child views don't show up. Reason why I need to call removeAllViews
is for the child views to not duplicate in the custom views.
These are some of the snippets from my custom view, I also implemented onLayout()
so whenever I display the custom views I get proper heights for layouting purposes. BarChartData
is just a model class for the data that should be displayed in this custom view:
public void setChartData(BarChartData data) {
this.chartData = data;
addBarDataToUi();
}
void addBarDataToUi() {
Log.d(TAG, "Add bar data to UI called");
if (chartData != null) {
//this.removeAllViews(); -> first one I tried, no luck, not displaying views after `addView`
//this.removeAllViewsInLayout(); -> tried this too but no luck
this.removeViewsInLayout(0, this.getChildCount()); // again, to no avail :(
for (int i = 0, count = chartData.getItemCount(); i < count; i++) {
addBarItemDataUi(chartData.getItemByPos(i));
}
Log.d(TAG, "Child count: " + this.getChildCount());
}
}
void addBarItemDataUi(BarItemData data) {
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
LinearLayout layout = (LinearLayout) inflater.inflate(R.layout.bar_chart_item, this, false);
FrameLayout mainLayout = (FrameLayout) layout.findViewById(R.id.bar_chart_item_main_layout);
//TextView topText = new TextView(getContext());
TextView topText = (TextView) layout.findViewById(R.id.bar_chart_item_top_text);
TextView bottomText = (TextView) layout.findViewById(R.id.bar_chart_item_bottom_text);
topText.setText(String.valueOf(data.percentage));
bottomText.setText(data.title);
mainLayout.setBackgroundColor(data.backgroundColor);
Log.d(TAG, "Height: " + this.getMeasuredHeight() + ", Top text height: " + topText.getMeasuredHeight());
int heightRel = (int) (data.getPercentageFractal() * (double) this.getMeasuredHeight());
mainLayout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, heightRel));
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 1f);
params.gravity = Gravity.BOTTOM;
layout.setLayoutParams(params);
this.addView(layout);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
Log.d(TAG, "On layout..");
if (chartData != null) {
addBarDataToUi();
}
}
Well, I have searched this problem, there are very few that came up, almost the same scenario and problem, but I think they have not resolved their problems about addView after removeAllViews.
I'm guessing that by calling the
removeAllViews()
function inside theaddBarDataToUi()
which is insideonLayout()
when the function gets called bysetChartData(BarChartData data)
it adds the child views which triggers theonLayout()
function which callsaddBarDataToUi()
and removes view and such in some kind of constant loop. The android documentation says toWhich I'm assuming might also include the onLayout() function as well.
My best suggestion is moving your
removeAllViews()
function call to inside yoursetChartData(BarChartData data)
function just before you calladdBarDataToUi()
Hope it helps