【问题标题】:Updating a single row in Android ListView every millisecond from ArrayAdapter从 ArrayAdapter 每毫秒更新 Android ListView 中的一行
【发布时间】:2015-10-18 09:05:07
【问题描述】:

我在上面设置了 ListView 和 ArrayAdapter。我的 ListView 单行包含 TextView 和启动按钮。单击按钮时,TextView 文本将每毫秒更改一次。我已经为它定义了计时器,但是当我更改 TextView 文本时,它不会出现在我的视图中。只有当我调用 notifyDataSetChanged 时它才会改变。但在这种情况下,每毫秒调用一次 notifyDataSetChanged,我的 ListView 就会崩溃。我怎么解决这个问题?除了我想说的是,我用 ViewHolder 模式实现了 ArrayAdapter 并覆盖了所有必要的方法。

【问题讨论】:

  • 只有一行的 Listview 看起来确实像......嗯......为什么要使用 Listview?
  • 我需要一个 ListView。然后我会为每一行添加 SeekBars
  • 好的,所以会有不止一行。无论如何,没有任何代码很难提供帮助。你能展示一些与问题相关的sn-ps吗?
  • 不幸的是在这台电脑上我没有源代码。你能建议我如何每毫秒更改一次列表视图行吗?
  • 你得到的结果是什么?

标签: android listview android-listview


【解决方案1】:

您应该使用 RecyclerView 它是一个灵活的视图,用于将有限的元素提供到大型数据集中。因此您可以使用它来控制在特定条件下应加载多少项目。你可以阅读 RecyclerView here

【讨论】:

    【解决方案2】:

    正如 Harshad 所写,您可以使用 RecyclerView,这是最好的方法。

    如果出于某种原因您不想要,您可以使用此行代码手动更新特定的列表视图行:

    View convertView = listview.getChildAt(rowIndex - listview.getFirstVisiblePosition());
    

    notifyDataChanged快多了...

    【讨论】:

    • 我可以从 ArrayAdapter 做到这一点吗?
    • 不确定我是否理解您的问题,但您仅使用此行代码更新 UI(您可以单独更新 ArrayAdapter)
    【解决方案3】:

    我另辟蹊径,像 RecyclerView 方法 void notifyItemChanged(int position),这样创建 CustomBaseAdapter 类:

    public abstract class CustomBaseAdapter implements ListAdapter, SpinnerAdapter {
    
        private final CustomDataSetObservable mDataSetObservable = new CustomDataSetObservable();
    
        public boolean hasStableIds() {
            return false;
        }
    
        public void registerDataSetObserver(DataSetObserver observer) {
            mDataSetObservable.registerObserver(observer);
        }
    
        public void unregisterDataSetObserver(DataSetObserver observer) {
            mDataSetObservable.unregisterObserver(observer);
        }
    
        public void notifyDataSetChanged() {
            mDataSetObservable.notifyChanged();
        }
    
        public void notifyItemChanged(int position) {
            mDataSetObservable.notifyItemChanged(position);
        }
    
        public void notifyDataSetInvalidated() {
            mDataSetObservable.notifyInvalidated();
        }
    
        public boolean areAllItemsEnabled() {
            return true;
        }
    
        public boolean isEnabled(int position) {
            return true;
        }
    
        public View getDropDownView(int position, View convertView, ViewGroup parent) {
            return getView(position, convertView, parent);
        }
    
        public int getItemViewType(int position) {
            return 0;
        }
    
        public int getViewTypeCount() {
            return 1;
        }
    
        public boolean isEmpty() {
            return getCount() == 0;
        }
    }
    

    不要忘记为 CustomAdapterClass 中的 mDataSetObservable 变量也创建一个 CustomDataSetObservable 类,如下所示:

    public class CustomDataSetObservable extends Observable<DataSetObserver> {
    
        public void notifyChanged() {
            synchronized(mObservers) {
                // since onChanged() is implemented by the app, it could do anything, including
                // removing itself from {@link mObservers} - and that could cause problems if
                // an iterator is used on the ArrayList {@link mObservers}.
                // to avoid such problems, just march thru the list in the reverse order.
                for (int i = mObservers.size() - 1; i >= 0; i--) {
                    mObservers.get(i).onChanged();
                }
            }
        }
    
        public void notifyInvalidated() {
            synchronized (mObservers) {
                for (int i = mObservers.size() - 1; i >= 0; i--) {
                    mObservers.get(i).onInvalidated();
                }
            }
        }
    
        public void notifyItemChanged(int position) {
            synchronized(mObservers) {
                // since onChanged() is implemented by the app, it could do anything, including
                // removing itself from {@link mObservers} - and that could cause problems if
                // an iterator is used on the ArrayList {@link mObservers}.
                // to avoid such problems, just march thru the list in the reverse order.
                mObservers.get(position).onChanged();
            }
        }
    }
    

    在 CustomBaseAdapter 类上有一个方法 notifyItemChanged(int position),当你想在任何地方更新行时,你可以调用该方法(从按钮单击或任何你想调用该方法的地方)。瞧!,您的单行将立即更新..

    希望此解决方案对您有所帮助..

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多