android - 在 Android 上创建的 View 的度量

标签 android android-layout android-widget

重新设计应用程序后,我们在创建新 View 时的加载时间更长(旧版本几乎没有图像,而且速度更快)。我们使用 ViewFlipper 来浏览 View 。创建的前两个 View 是两个带有 ListView 的布局,其元素具有背景图像和其他图形。巧合的是,我们发现每次创建新 View 并将其放入 View 堆栈时,应用程序都会计算每个现有 View 的尺寸(其中多次调用 ListView 适配器的 getView() 方法)。每次调用的跟踪日志如下所示:

LinearLayout.measureChildBeforeLayout(View, int, int, int, int, int) line: 1369 LinearLayout.measureVertical(int, int) line: 660 LinearLayout.onMeasure(int, int) line: 553 LinearLayout(View).measure(int, int) line: 12937 TabHost(ViewGroup).measureChildWithMargins(View, int, int, int, int) line: 5045 TabHost(FrameLayout).onMeasure(int, int) line: 293 TabHost(View).measure(int, int) line: 12937 RelativeLayout.measureChildHorizontal(View, RelativeLayout$LayoutParams, int, int) line: 594 RelativeLayout.onMeasure(int, int) line: 376 RelativeLayout(View).measure(int, int) line: 12937 FrameLayout(ViewGroup).measureChildWithMargins(View, int, int, int, int) line: 5045 FrameLayout.onMeasure(int, int) line: 293 FrameLayout(View).measure(int, int) line: 12937 LinearLayout(ViewGroup).measureChildWithMargins(View, int, int, int, int) line: 5045 LinearLayout.measureChildBeforeLayout(View, int, int, int, int, int) line: 1369 LinearLayout.measureVertical(int, int) line: 660 LinearLayout.onMeasure(int, int) line: 553 LinearLayout(View).measure(int, int) line: 12937 PhoneWindow$DecorView(ViewGroup).measureChildWithMargins(View, int, int, int, int) line: 5045 PhoneWindow$DecorView(FrameLayout).onMeasure(int, int) line: 293 PhoneWindow$DecorView.onMeasure(int, int) line: 2180 PhoneWindow$DecorView(View).measure(int, int) line: 12937

等等... 我认为这就是应用程序变得如此缓慢的原因。 我可以做些什么来阻止应用执行这些措施或使应用更快?

ListAdapter getView():

    public View getView(int pos, View convertView, ViewGroup parent) {

    View row;
    Entry entry = null;
    if (objects.get(pos) instanceof Entry) {
        entry = (Entry) objects.get(pos) ;

        Boolean isGroupedEntry;
        if (entry.getGroup() != null && entry.isGroupedEntry()) {
            isGroupedEntry = true;
        } else {
            isGroupedEntry = false;
        }

        if (convertView != null) {
            row = convertView;
        } else {
            row = new EntryBoxFrameLayout(getContext());
        }

        ((EntryBoxFrameLayout) row).configureFor(entry);

    } else {
        row = new View(ContentManager.getInstance().getContext());
    }

    row.setSelected(false);
    row.setTag(pos);
    return row;
}

在 configureFor() 中我设置了一些文本然后:

        if (entry.getUserIsSignedUp() > 0) {
        this.setBackgroundColor("4A4A4A");
        this.findViewById(R.id.star).setVisibility(View.VISIBLE);
        this.findViewById(R.id.entry_face).setBackgroundResource(R.drawable.entry_face_loggedin);
        fulldate.setTextColor(Color.BLACK);
    } else {
        this.setBackgroundColor(entry.getColorHex());
        this.findViewById(R.id.star).setVisibility(View.INVISIBLE);
        this.findViewById(R.id.entry_face).setBackgroundResource(R.drawable.entry_face);
        fulldate.setTextColor(Color.WHITE);
    }

    if (entry.getGroup() != null) {
        this.findViewById(R.id.imgGroupArrow).setVisibility(View.VISIBLE);
        if (entry.isGroupExpanded()) {
            ((ImageView)this.findViewById(R.id.imgGroupArrow)).setImageResource(R.drawable.entry_up_arrow);
        } else {
            ((ImageView)this.findViewById(R.id.imgGroupArrow)).setImageResource(R.drawable.entry_down_arrow);
        }
        this.setGroupContainer(true);
    } else {
        this.findViewById(R.id.imgGroupArrow).setVisibility(View.INVISIBLE);
        this.setGroupContainer(false);
    }

    String filename = entry.getCacheFilename();
    Drawable entryimage = null;
    if (filename != null) {
        try {
            FileInputStream input = ContentManager.getInstance().getContext().openFileInput(filename);
            entryimage = new BitmapDrawable(ContentManager.getInstance().getContext().getResources(), input);
            input.close();
        } catch (Exception e) {
            Log.e(e.getLocalizedMessage());
        }
    }

    if (entryimage != null) {
        this.getImageView().setImageDrawable(entryimage);
    } else {
        this.getImageView().setImageResource(R.drawable.entry_placeholder);
    }

最佳答案

getView() 方法正在减慢您的应用程序。 listView 回收 View 对象以提高性能。

有许多学习资源涵盖了这一点。

来自 google I/O 大会和 listView 的创建者:Romain Guy

图片优化

更多代码示例:

  • Google 优化 ListView
  • 用于延迟加载 ListView 的 Google
  • Google for convertview, viewholder listview

关于android - 在 Android 上创建的 View 的度量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14340225/

相关文章:

java - 在android中使用sharedpreferences保存微调器状态

带有 ListView 的 Android 小部件无法正确加载项目

android - 如何对 Android Canvas 上的剪辑边界进行抗锯齿处理?

android - 滑动 TabLayout 选项卡不可点击

android - 以编程方式连接到蓝牙设备

java - RemoteViews.setImageViewResource 不起作用?

android - 如何使用 eclipse adt 将新库添加到 android 依赖项?

java - 如何从我在android中的应用程序启动另一个应用程序

android - Android 中的 ExpandabeListView 不支持 ChildClickListener

Android:通过 TextView 中的链接启动 Activity