Android ListView如何实时更新动态数据?

发布于 2024-11-04 11:30:24 字数 589 浏览 5 评论 0原文

我有一个后台线程加载我想在 Android ListView 中显示的数据。数据变化非常频繁(即每秒1-2次)。有时,数据集中的行数也会发生变化(但肯定不如单元格中的数据变化那么频繁)。

据我所知,有两种方法可以更新单元格中的数据:

  1. 让后台线程通知 UI 线程新数据已准备好,然后 UI 线程可以调用 BaseAdapter.notifyDataSetChanged()。但是,我在不止一处读到过,如果经常调用该方法,速度会很慢,因为 ListView 必须重构其所有子视图 View。

  2. 如果数据集计数未更改,我可能会找到与更改的数据关联的所有可见 ListView 单元格,并手动更新值,而无需调用 notificationDataSetChanged()。这可能会起作用,但我认为不幸的是,当列表适配器应该在我通知它时为我处理更新通知和机制时,我必须手动更新视图。如果数据集计数随时间变化(即,不仅 ListView 的每个单元格内的数据发生变化,而且 ListView 中的单元格总数可能根据提供实时数据的后台线程增长或缩小,此方法也将不起作用)。

我当然很欣赏实现此场景的其他人的想法,以及他们如何优化代码简单性以及最重要的是性能。

I have a background thread loading data which I want to display in an Android ListView. The data changes very often (i.e. 1-2 times per second). Sometimes the number of rows in the dataset changes too (but certainly not as often as the data in the cells changes).

There are two ways to update the data in the cells, as far as I can tell:

  1. Have the background thread notify the UI thread that new data is ready, and the UI thread can then call BaseAdapter.notifyDataSetChanged(). However, I have read in more than one place that if that method is called often, it will be slow, because the ListView has to restructure all of its subviews Views.

  2. If the dataset count has not changed, I could possibly find all of the visible ListView cells that are associated with the changed data, and update the values manually without calling notifyDataSetChanged(). This would probably work, but I think its unfortunate that I have to update the views manually when the List Adapter is supposed to handle the update notifications and mechanisms for me when I notify it. This method also won't work if the dataset count changes over time (i.e. not only is the data within each cell of the ListView changing, but the total number of cells in the ListView can grow or shrink based on the background thread supplying realtime data).

I would certainly appreciate thoughts from others who have implemented this scenario, and how they optimized code simplicity and most importantly, performance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

雨后彩虹 2024-11-11 11:30:24

我尝试了 ListView,如果您有实时数据并且想要ListView 以更好的性能进行更新。

notifyDataSetChanged() 导致 ListView 重建其整个 View 层次结构,如果您频繁调用它(即每秒一次),则速度会非常慢。

注(2014)。如果您使用带有 ViewHolder 模式的普通现代 ListView,则这不适用。您只需调用“notifyDataSetChanged”即可。它的效率非常高,因为 Android 知道只更新屏幕上的单元格。

我实现了一种方案,如果我的数据集大小从一次更新更改为下一次更新,我会调用 notifyDataSetChanged() 。如果数据集大小从一次更新到下一次更新保持不变(这样,当需要重绘数据时,ListView 中的单元格数量与之前相同),那么我会迭代ListView.getFirstVisiblePosition()getLastVisiblePosition(),并且仅更新可见单元格。

I experimented with ListView, and you essentially have to update the ListView cells manually without calling notifyDataSetChanged() if you have realtime data and you want the ListView to update with better performance.

notifyDataSetChanged() causes the ListView to rebuild its entire View hierarchy is very slow if you are calling it frequently (i.e. once every second).

Note (2014). This DOES NOT APPLY if you are using normal modern ListView with a ViewHolder pattern. You simply call 'notifyDataSetChanged' and that's all there is to it. It is incredibly efficient as Android knows to only update the cells on the screen.

I implemented a scheme where if my data set size changed from one update to the next, I call notifyDataSetChanged(). If the data set size remained constant from one update to the next (such that the number of cells in the ListView is the same as before when a redraw of the data is needed), then I iterate over the ListView.getFirstVisiblePosition() : getLastVisiblePosition(), and update the visible cells only.

囚你心 2024-11-11 11:30:24

我曾经使用 notifyDataSetChanged() 实现了如下代码所示的过滤器,并且没有出现任何问题。

我还手动修改了列表的视图。两者都运作良好。在某些情况下,我更喜欢手动修改数据,因为它更快并且不会影响整个列表。

无论如何,视图是在需要出现在屏幕上时创建的,而在离开屏幕时会被删除,因此,如果修改用于创建视图的数据,如果用户滚动 ListView 并且视图会脱离屏幕理论上,一旦视图再次进入屏幕,就会使用新数据创建视图。

我建议您尝试下面的代码来了解 notifyDataSetChanged() 的工作原理并确定它是否适合您。

public class ListText extends Activity {


    private ListView lv1;
    private Followed followedFriends[];
    ListView lst;
    EditText edt;
    FollowedFilterableAdapter arrad;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        lv1=(ListView)findViewById(R.id.listView1);
        edt = (EditText) findViewById(R.id.editText1);

        followedFriends = new Followed[10];
        followedFriends[0] = new Followed("Alan Walder", "0123456789", "1");
        followedFriends[1] = new Followed("Alberto Levi", "123456789", "1");
        followedFriends[2] = new Followed("David Rodan", "23456789", "1");
        followedFriends[3] = new Followed("David Stern", "3456789", "1");
        followedFriends[4] = new Followed("Elias Jawa", "456789", "1");
        followedFriends[5] = new Followed("Elian Moreno", "56789", "1");
        followedFriends[6] = new Followed("Jonathan Rodan", "6789", "1");
        followedFriends[7] = new Followed("Klara Rodan", "789", "1");
        followedFriends[8] = new Followed("Willy Rosales", "89", "1");
        followedFriends[9] = new Followed("ZZZ ZZZ", "9", "1");


        arrad =  new FollowedFilterableAdapter(followedFriends);
        lv1.setAdapter(arrad);

        addTextChangeList();
    }

    private void addTextChangeList()
    {
        edt.addTextChangedListener(new TextWatcher()
        {


            public void onTextChanged( CharSequence arg0, int arg1, int arg2, int arg3)
            {
                // TODO Auto-generated method stub

            }

            public void beforeTextChanged( CharSequence arg0, int arg1, int arg2, int arg3)
            {
                // TODO Auto-generated method stub

            }



            public void afterTextChanged( Editable arg0)
            {
                // TODO Auto-generated method stub
                ListText.this.arrad.getFilter().filter(arg0);
            }
        });

    }


    ///////////////////////////////////Internal classes ////////////////////////

    private class Followed
    {
        private String _name;
        private String _id;
        private boolean _followed;
        private String _picToDelete = "http://images.wikia.com/tibia/en/images/7/72/Skeleton.gif";

        private Followed(String name, String id, String followed)
        {
            this._name = name;
            this._id = id;
            this._followed = followed.equals("1");
        }

        public String toString(){return _name;}
        public String getName(){return _name;}
        public String getId(){return _id;}
        public boolean idFollowed(){return _followed;}
        public String getURL(){return _picToDelete;}
    }

    /////////////////////////////////////////Adapter//////////////////////////////////

    private class FollowedFilterableAdapter extends BaseAdapter implements Filterable
    {
        /**
         * Lock used to modify the content of {@link #mObjects}. Any write operation
         * performed on the array should be synchronized on this lock. This lock is also
         * used by the filter (see {@link #getFilter()} to make a synchronized copy of
         * the original array of data.
         */
        private final Object _Lock = new Object();

        /*/**
         * Indicates whether or not {@link #notifyDataSetChanged()} must be called whenever
         * {@link #mObjects} is modified.
         */
        //private boolean _NotifyOnChange = true;

        private List<Followed> _Objects;

        private ArrayList<Followed> _followedFriends;
        private ArrayFilter _Filter;

        public FollowedFilterableAdapter(Followed[] followedFriends)
        {
            _Objects = Arrays.asList(followedFriends);
        }

        public int getCount() {
            return _Objects.size();
        }

        public Followed getItem(int position) {
            return _Objects.get(position);
        }

        public long getItemId(int position) {
            return position;
        }

        public View getView(int position, View convertView, ViewGroup parent) {
            int px = 2;

            //Creating the CategoryRow that represents the row
            LinearLayout lstItem = new LinearLayout(ListText.this);
            lstItem.setLayoutParams(new ListView.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT,1));
            lstItem.setOrientation(LinearLayout.HORIZONTAL);
            //lstItem.setPadding(px,px,px,px);
            lstItem.setGravity(Gravity.CENTER_VERTICAL);
            /*<LinearLayout android:layout_width="fill_parent"
                            android:layout_height="wrap_content" android:orientation="horizontal"
                            android:padding="2dp" android:gravity="center_vertical">*/

            //Adding the Image
            ImageView icon = new ImageView(ListText.this);
            icon.setLayoutParams(new LayoutParams(50,50));
            icon.setImageResource(R.drawable.icon);
            icon.setScaleType(ScaleType.CENTER_CROP);
            //icon.setImage(tag.getId());
            /*<ImageView android:layout_width="50dp" android:id="@+id/iconFollList"
                                android:src="@drawable/icon" android:layout_height="40dp"></ImageView>*/

            //Adding the Linear Layout for the text
            RelativeLayout lstTextx = new RelativeLayout(ListText.this);
            lstTextx.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT,1));
            lstTextx.setGravity(Gravity.CENTER_VERTICAL);
            lstTextx.setPadding(5, px, px, px);
            /*<LinearLayout android:layout_width="fill_parent"
                                android:layout_height="wrap_content" android:orientation="vertical"
                                android:padding="2dp" android:paddingLeft="5dp">*/

            //Adding the Name of the person who commented
            TextView txtCommenter = new TextView(ListText.this);
            txtCommenter.setLayoutParams(
                    new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,
                    LayoutParams.WRAP_CONTENT));
            txtCommenter.setTextSize(10);
            txtCommenter.setTypeface(Typeface.create("Sans Serif", Typeface.BOLD));
            txtCommenter.setText(_Objects.get(position).getName());
            /*<TextView android:text="TextView" android:id="@+id/FollListCategory"
                                    android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView>*/


            ImageView btnFollowed = new ImageView(ListText.this);
            RelativeLayout.LayoutParams params = 
                new RelativeLayout.LayoutParams(80,30);
            params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
            btnFollowed.setLayoutParams(params);
            btnFollowed.setImageResource(R.drawable.icon);
            btnFollowed.setScaleType(ScaleType.FIT_XY);

            //Arming the View
            lstItem.addView(icon, 0);
            lstTextx.addView(txtCommenter, 0);
            lstTextx.addView(btnFollowed,1);
            lstItem.addView(lstTextx,1);

            return lstItem;
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public void notifyDataSetChanged() {
            super.notifyDataSetChanged();
            //_NotifyOnChange = true;
        }

        /*public void setNotifyOnChange(boolean notifyOnChange) {
            _NotifyOnChange = notifyOnChange;
        }*/

        public Filter getFilter() {
            if (_Filter == null) {
                _Filter = new ArrayFilter();
            }
            return _Filter;
        }

        /////////////////////Second Level Internal classes //////////////////////////

        private class ArrayFilter extends Filter {
            @Override
            protected FilterResults performFiltering(CharSequence prefix) {
                FilterResults results = new FilterResults();

                if (_followedFriends == null) {
                    synchronized (_Lock) {
                        _followedFriends = new ArrayList<Followed>(_Objects);
                    }
                }

                if (prefix == null || prefix.length() == 0) {
                    synchronized (_Lock) {
                        ArrayList<Followed> list = new ArrayList<Followed>(_followedFriends);
                        results.values = list;
                        results.count = list.size();
                    }
                } else {
                    String prefixString = prefix.toString().toLowerCase();

                    final ArrayList<Followed> values = _followedFriends;
                    final int count = values.size();

                    final ArrayList<Followed> newValues = new ArrayList<Followed>(count);

                    for (int i = 0; i < count; i++) {
                        final Followed value = values.get(i);
                        final String valueText = value.toString().toLowerCase();

                        // First match against the whole, non-splitted value
                        if (valueText.startsWith(prefixString)) {
                            newValues.add(value);
                        } else {
                            final String[] words = valueText.split(" ");
                            final int wordCount = words.length;

                            for (int k = 0; k < wordCount; k++) {
                                if (words[k].startsWith(prefixString)) {
                                    newValues.add(value);
                                    break;
                                }
                            }
                        }
                    }

                    results.values = newValues;
                    results.count = newValues.size();
                }

                return results;
            }

            @Override
            protected void publishResults(CharSequence constraint, FilterResults results) {
                //no inspection unchecked
                _Objects = (List<Followed>) results.values;
                if (results.count > 0) {
                    notifyDataSetChanged();
                } else {
                    notifyDataSetInvalidated();
                }
            }
        }
    }

xml

    <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <EditText android:text="" android:layout_height="wrap_content"
    android:id="@+id/editText1" android:layout_width="match_parent"></EditText>
    <ListView android:id="@+id/listView1" android:layout_height="fill_parent"
    android:layout_width="match_parent" android:layout_weight="1"></ListView>

</LinearLayout>

希望这有帮助。

I once implemented a filter like the code beolow using notifyDataSetChanged() and had no problems with it.

I've also modified the views of a List on the go manually. Both have worked well. In some case I prefear to modify the data manually because its faster and because itdoesn't affect the whole list.

Anyway, views are created on the go when they need to apear on the screen and are deleted when they leave the screen, so if you modify the data used to create the views, if the user scrolls the ListView and the views get out of the screen, in theory, the views will be created with the new data once they come again into the screen.

I would recommend you to try the code below to understand how does notifyDataSetChanged() work and decide if it works for you.

public class ListText extends Activity {


    private ListView lv1;
    private Followed followedFriends[];
    ListView lst;
    EditText edt;
    FollowedFilterableAdapter arrad;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        lv1=(ListView)findViewById(R.id.listView1);
        edt = (EditText) findViewById(R.id.editText1);

        followedFriends = new Followed[10];
        followedFriends[0] = new Followed("Alan Walder", "0123456789", "1");
        followedFriends[1] = new Followed("Alberto Levi", "123456789", "1");
        followedFriends[2] = new Followed("David Rodan", "23456789", "1");
        followedFriends[3] = new Followed("David Stern", "3456789", "1");
        followedFriends[4] = new Followed("Elias Jawa", "456789", "1");
        followedFriends[5] = new Followed("Elian Moreno", "56789", "1");
        followedFriends[6] = new Followed("Jonathan Rodan", "6789", "1");
        followedFriends[7] = new Followed("Klara Rodan", "789", "1");
        followedFriends[8] = new Followed("Willy Rosales", "89", "1");
        followedFriends[9] = new Followed("ZZZ ZZZ", "9", "1");


        arrad =  new FollowedFilterableAdapter(followedFriends);
        lv1.setAdapter(arrad);

        addTextChangeList();
    }

    private void addTextChangeList()
    {
        edt.addTextChangedListener(new TextWatcher()
        {


            public void onTextChanged( CharSequence arg0, int arg1, int arg2, int arg3)
            {
                // TODO Auto-generated method stub

            }

            public void beforeTextChanged( CharSequence arg0, int arg1, int arg2, int arg3)
            {
                // TODO Auto-generated method stub

            }



            public void afterTextChanged( Editable arg0)
            {
                // TODO Auto-generated method stub
                ListText.this.arrad.getFilter().filter(arg0);
            }
        });

    }


    ///////////////////////////////////Internal classes ////////////////////////

    private class Followed
    {
        private String _name;
        private String _id;
        private boolean _followed;
        private String _picToDelete = "http://images.wikia.com/tibia/en/images/7/72/Skeleton.gif";

        private Followed(String name, String id, String followed)
        {
            this._name = name;
            this._id = id;
            this._followed = followed.equals("1");
        }

        public String toString(){return _name;}
        public String getName(){return _name;}
        public String getId(){return _id;}
        public boolean idFollowed(){return _followed;}
        public String getURL(){return _picToDelete;}
    }

    /////////////////////////////////////////Adapter//////////////////////////////////

    private class FollowedFilterableAdapter extends BaseAdapter implements Filterable
    {
        /**
         * Lock used to modify the content of {@link #mObjects}. Any write operation
         * performed on the array should be synchronized on this lock. This lock is also
         * used by the filter (see {@link #getFilter()} to make a synchronized copy of
         * the original array of data.
         */
        private final Object _Lock = new Object();

        /*/**
         * Indicates whether or not {@link #notifyDataSetChanged()} must be called whenever
         * {@link #mObjects} is modified.
         */
        //private boolean _NotifyOnChange = true;

        private List<Followed> _Objects;

        private ArrayList<Followed> _followedFriends;
        private ArrayFilter _Filter;

        public FollowedFilterableAdapter(Followed[] followedFriends)
        {
            _Objects = Arrays.asList(followedFriends);
        }

        public int getCount() {
            return _Objects.size();
        }

        public Followed getItem(int position) {
            return _Objects.get(position);
        }

        public long getItemId(int position) {
            return position;
        }

        public View getView(int position, View convertView, ViewGroup parent) {
            int px = 2;

            //Creating the CategoryRow that represents the row
            LinearLayout lstItem = new LinearLayout(ListText.this);
            lstItem.setLayoutParams(new ListView.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT,1));
            lstItem.setOrientation(LinearLayout.HORIZONTAL);
            //lstItem.setPadding(px,px,px,px);
            lstItem.setGravity(Gravity.CENTER_VERTICAL);
            /*<LinearLayout android:layout_width="fill_parent"
                            android:layout_height="wrap_content" android:orientation="horizontal"
                            android:padding="2dp" android:gravity="center_vertical">*/

            //Adding the Image
            ImageView icon = new ImageView(ListText.this);
            icon.setLayoutParams(new LayoutParams(50,50));
            icon.setImageResource(R.drawable.icon);
            icon.setScaleType(ScaleType.CENTER_CROP);
            //icon.setImage(tag.getId());
            /*<ImageView android:layout_width="50dp" android:id="@+id/iconFollList"
                                android:src="@drawable/icon" android:layout_height="40dp"></ImageView>*/

            //Adding the Linear Layout for the text
            RelativeLayout lstTextx = new RelativeLayout(ListText.this);
            lstTextx.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT,1));
            lstTextx.setGravity(Gravity.CENTER_VERTICAL);
            lstTextx.setPadding(5, px, px, px);
            /*<LinearLayout android:layout_width="fill_parent"
                                android:layout_height="wrap_content" android:orientation="vertical"
                                android:padding="2dp" android:paddingLeft="5dp">*/

            //Adding the Name of the person who commented
            TextView txtCommenter = new TextView(ListText.this);
            txtCommenter.setLayoutParams(
                    new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,
                    LayoutParams.WRAP_CONTENT));
            txtCommenter.setTextSize(10);
            txtCommenter.setTypeface(Typeface.create("Sans Serif", Typeface.BOLD));
            txtCommenter.setText(_Objects.get(position).getName());
            /*<TextView android:text="TextView" android:id="@+id/FollListCategory"
                                    android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView>*/


            ImageView btnFollowed = new ImageView(ListText.this);
            RelativeLayout.LayoutParams params = 
                new RelativeLayout.LayoutParams(80,30);
            params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
            btnFollowed.setLayoutParams(params);
            btnFollowed.setImageResource(R.drawable.icon);
            btnFollowed.setScaleType(ScaleType.FIT_XY);

            //Arming the View
            lstItem.addView(icon, 0);
            lstTextx.addView(txtCommenter, 0);
            lstTextx.addView(btnFollowed,1);
            lstItem.addView(lstTextx,1);

            return lstItem;
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public void notifyDataSetChanged() {
            super.notifyDataSetChanged();
            //_NotifyOnChange = true;
        }

        /*public void setNotifyOnChange(boolean notifyOnChange) {
            _NotifyOnChange = notifyOnChange;
        }*/

        public Filter getFilter() {
            if (_Filter == null) {
                _Filter = new ArrayFilter();
            }
            return _Filter;
        }

        /////////////////////Second Level Internal classes //////////////////////////

        private class ArrayFilter extends Filter {
            @Override
            protected FilterResults performFiltering(CharSequence prefix) {
                FilterResults results = new FilterResults();

                if (_followedFriends == null) {
                    synchronized (_Lock) {
                        _followedFriends = new ArrayList<Followed>(_Objects);
                    }
                }

                if (prefix == null || prefix.length() == 0) {
                    synchronized (_Lock) {
                        ArrayList<Followed> list = new ArrayList<Followed>(_followedFriends);
                        results.values = list;
                        results.count = list.size();
                    }
                } else {
                    String prefixString = prefix.toString().toLowerCase();

                    final ArrayList<Followed> values = _followedFriends;
                    final int count = values.size();

                    final ArrayList<Followed> newValues = new ArrayList<Followed>(count);

                    for (int i = 0; i < count; i++) {
                        final Followed value = values.get(i);
                        final String valueText = value.toString().toLowerCase();

                        // First match against the whole, non-splitted value
                        if (valueText.startsWith(prefixString)) {
                            newValues.add(value);
                        } else {
                            final String[] words = valueText.split(" ");
                            final int wordCount = words.length;

                            for (int k = 0; k < wordCount; k++) {
                                if (words[k].startsWith(prefixString)) {
                                    newValues.add(value);
                                    break;
                                }
                            }
                        }
                    }

                    results.values = newValues;
                    results.count = newValues.size();
                }

                return results;
            }

            @Override
            protected void publishResults(CharSequence constraint, FilterResults results) {
                //no inspection unchecked
                _Objects = (List<Followed>) results.values;
                if (results.count > 0) {
                    notifyDataSetChanged();
                } else {
                    notifyDataSetInvalidated();
                }
            }
        }
    }

xml

    <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <EditText android:text="" android:layout_height="wrap_content"
    android:id="@+id/editText1" android:layout_width="match_parent"></EditText>
    <ListView android:id="@+id/listView1" android:layout_height="fill_parent"
    android:layout_width="match_parent" android:layout_weight="1"></ListView>

</LinearLayout>

Hope this helps.

执手闯天涯 2024-11-11 11:30:24

也许你可以在 UI 线程上设置一个 Handler。您需要创建一个实现 Runnable 的类。将 ArrayList 传递给此类。在 run() 方法中,使用 ArrayList 作为参数创建适配器,然后在 ListView 上执行 setAapter。就是这样。你完成了。
要启动您的处理程序:只需从您的工作线程执行此操作: handler.Post(new MyUpdateToUI() );
就是这样。我希望它对你来说足够有效?

Maybe you can set a Handler on the UI thread. You need to create a class which implements Runnable. Pass an ArrayList to this class. In the run() method create the adaptor with the ArrayList as a parameter, then do a setAapter on the ListView. That's it. You're done.
To launch your handler : just to this from your worker thread : handler.Post(new MyUpdateToUI() );
That's it. I hope it is efficient enough for you?

远山浅 2024-11-11 11:30:24

我遇到了非常类似的情况,我将列表视图的文本视图存储在哈希图中,其中每个文本视图都有一个标签来识别它。当流数据到达时,我所做的就是在找到正确的数据后在文本视图上发布一个可运行的数据并立即更新它们。
然而,尽管更新是即时的,但 UI 遇到了阻力并且变得缓慢,因为我每秒更新大约 30 个文本视图。我将 Listview 放在 ViewPager 内的一个片段中,当流式传输打开时,UI 线程似乎全部被堵塞和阻塞。
因此,就 UI 线程的用户体验和性能而言,我强烈建议不要手动更新 Listview 中的 Textview

I faced a very similar situation where I stored the textviews of List View in a Hashmap where each textview had a tag to have it identified. When the streaming data arrived, all I did was post a runnable on the textview after finding the correct one and got them updated in no time.
However, though the updates were instantaneous the UI faced a drag and went sluggish as I was updating about 30 textviews per second. I had my Listview in a fragment inside a ViewPager and it seemed the UI thread was all clogged up and blocked when streaming was on.
Hence, I strongly advise against manual updating of the Textviews in a Listview as far as User experience and performance of the UI thread is concerned

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文