【问题标题】:addView not displaying after removeAllViews on custom view在自定义视图上的 removeAllViews 后 addView 不显示
【发布时间】:2015-08-28 12:04:37
【问题描述】:

我正在构建一个自定义视图,有点像自定义条形图。我正在为这个扩展LinearLayout。然后自定义视图从数据中填充视图。问题是,每当我想要“刷新”视图时,我都会调用removeAllViews() 和类似的方法,因此自定义视图布局是干净的,然后要重新填充数据,我调用addView(),但子视图不要不出现。我需要调用removeAllViews 的原因是子视图不会在自定义视图中重复。

这些是我的自定义视图中的一些 sn-ps,我还实现了onLayout(),因此每当我显示自定义视图时,我都会获得适当的高度以进行布局。 BarChartData 只是应在此自定义视图中显示的数据的模型类:

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();
    }
}

嗯,这个问题我搜过了,发现的很少,几乎是一样的场景和问题,但是我认为他们在removeAllViews之后关于addView的问题并没有解决。

【问题讨论】:

    标签: android android-layout android-linearlayout android-custom-view


    【解决方案1】:

    我猜测通过在addBarDataToUi() 内部调用addBarDataToUi() 内部的removeAllViews() 函数,当该函数被setChartData(BarChartData data) 调用时,它会添加子视图,从而触发调用@ 的onLayout() 函数987654327@ 并在某种恒定循环中删除视图等。 android文档说

    避免在onDraw() 或任何相关函数中使用removeAllViews() http://developer.android.com/reference/android/view/ViewGroup.html#removeAllViews()

    我假设也可能包括 onLayout() 函数。

    我最好的建议是在您调用 addBarDataToUi() 之前将您的 removeAllViews() 函数调用移到您的 setChartData(BarChartData data) 函数中

    希望对你有帮助

    【讨论】:

    • 嗯,我还以为onLayout()是一个相关的函数,刚试过把addBarDataToUi()onLayout()去掉
    • 感谢您的提示。我发现从线程运行的addOnLayoutChangeListener 并不总是重绘重新创建的布局(我在其中添加了视图)。但所有参数都是正确的。旋转设备时,变化变得可见。然后我调用了另一个方法:runOnUiThread 并在其中layout.post(new Runnable ...)
    猜你喜欢
    • 2014-05-28
    • 1970-01-01
    • 2016-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-25
    相关资源
    最近更新 更多