addView not displaying after removeAllViews on custom view

1.9k Views Asked by At

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.

1

There are 1 best solutions below

2
On

I'm guessing that by calling the removeAllViews() function inside the addBarDataToUi() which is inside onLayout() when the function gets called by setChartData(BarChartData data) it adds the child views which triggers the onLayout() function which calls addBarDataToUi() and removes view and such in some kind of constant loop. The android documentation says to

avoid using removeAllViews() inside onDraw() or any related function http://developer.android.com/reference/android/view/ViewGroup.html#removeAllViews()

Which I'm assuming might also include the onLayout() function as well.

My best suggestion is moving your removeAllViews() function call to inside your setChartData(BarChartData data) function just before you call addBarDataToUi()

Hope it helps