【问题标题】:Custom listview scrollin isn't smooth自定义列表视图滚动不流畅
【发布时间】:2012-02-20 09:46:22
【问题描述】:

我创建了一个自定义列表视图,除了列表不能平滑滚动之外,它的效果很好。它波涛汹涌而缓慢。

这是我填充列表视图的代码:

@Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View v = convertView;
            if (v == null) {
                LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = vi.inflate(R.layout.listitem, null);
        }

        FilmRecord film = films.get(position);
        if (film != null) {
            TextView filmTitle = (TextView) v.findViewById(R.id.filmtitle);
            TextView filmShowingDate = (TextView) v.findViewById(R.id.filmshowingtime);
            TextView filmAdded = (TextView) v.findViewById(R.id.filmadded);
            TextView filmLocations = (TextView) v.findViewById(R.id.filmlocations);
            TextView filmDescription = (TextView) v.findViewById(R.id.filmdescription);
            TextView filmProvider = (TextView) v.findViewById(R.id.filmprovider);
            TextView filmTicketUrl = (TextView) v.findViewById(R.id.filmticketurl);


            if (filmTitle != null) {
                filmTitle.setText(film.filmTitle);
            }

            if(filmDescription != null) {
                filmDescription.setText(film.filmDescription );
            }

            if(filmLocations != null) {
                filmLocations.setText(film.filmLocations );
            }

            if(filmShowingDate != null) {
                filmShowingDate.setText("Showing: " + film.filmShowingDate );
            }

            if(filmAdded != null) {
                filmAdded.setText("Added on: " + film.filmAdded );
            }

            if(filmProvider != null) {
                filmProvider.setText(film.filmProvider );
            }

            if(filmTicketUrl != null) {
                filmTicketUrl.setText(film.filmTicketUrl );
            }
        }

        //Check who the provider is and set the imageview to provider logo
        ImageView imageView = (ImageView) v.findViewById(R.id.providerImage);
        if(film.filmProvider.equals("Cineworld")) {
            Log.d("Provider", "Provider is Cineworld");
            imageView.setImageResource(R.drawable.cineworld);
        }
        else if(film.filmProvider.equals("Show Film Fist")){
            Log.d("Provider", "Provider is Show Film Fist");
            imageView.setImageResource(R.drawable.show_film_first);
        }

        return v;
    }

有没有人在创建自定义列表视图时遇到过类似的问题?一如既往的任何帮助将不胜感激:)

【问题讨论】:

  • 你需要改变你的逻辑。您正在检查每个字段是否为 null,我认为当您在不检查 null 的情况下设置文本时,它不会给出任何错误。 Showing: 和Added on: 必须有两个if。但是您可以通过在 POJO 中设置这两个 pre_text 来删除这两个。希望它会清除。

标签: android listview custom-lists


【解决方案1】:

你需要使用ViewHolder的方法。

因为按 id 查找视图也需要时间来执行。

通过使用ViewHolder 方法,您将能够通过缓存视图来最大程度地减少在通过 id 查找视图期间创建的负载:)

Here 是很好的教程。

编辑:

ViewHolder 方法的作用是:

假设您的ListView 中一次有 4 个可见项目。即使您滚动到 ListView 中的第 1000 个项目,您也必须将 View 膨胀 4 次和 findViewById() 4 次。

但是如果你不使用ViewHolder并且你已经放了

if (v == null) {
   LayoutInflater vi = ...;
}else{
   //... other implementation 
}

您只需将View 充气4 次,但findViewById() 将在getView() 被调用时每次被调用(通常在ListView 被滚动时)。

编码愉快!

【讨论】:

  • 再次感谢本教程。我已经相应地实现了代码。一旦我向下浏览列表,我就会得到重复的列表项。例如。第 5 行和第 6 行的内容与第 0 行相同。有什么想法我哪里出错了吗?
  • 嗨 Adil,感谢您的回复 :) 我一直在调整代码,它不会重复列表项。但是现在我又回到了我不平滑滚动的情况 lol getView() 代码位于Pastie
  • 更新后的代码有效。非常感谢您帮助我:) 并感谢您的 paste.org 链接。 cmets 的便捷站点。
【解决方案2】:

我今天遇到了同样的问题,在使用 viewHolder 模式时滚动仍然很慢,直到我想向同事展示这个问题并注意到滚动很流畅。 所以我的问题是我连接到调试器并减慢了速度。

【讨论】:

    【解决方案3】:

    请参考这个问题并在那里查看我的答案。它显示了您应该如何在自定义适配器类中声明您的组件。对您的类进行这些更改肯定会解决您的问题,因为我在这里提出的问题也有类似的问题你的:Scrolable ListView with costumized BaseAdapter is very slow

    【讨论】:

      【解决方案4】:

      你在films.get(position)做什么?

      如果您正在从数据库中读取,那么您的滚动可能真的很糟糕......

      当使用数据库时,您应该在 onCreate 期间将数据加载到适配器中,可能类似这样(但使用您之前的列表视图布局等)

      @Override
      public void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.main);
      
          List<FilmRecord> values = films.getAllFilms();
      
      
          ArrayAdapter<FilmRecord> adapter = new ArrayAdapter<FilmRecord>(this,
                      your_list_item_layout_id, values);
          your_list_view.setListAdapter(adapter);
      }
      

      getView() 方法中,您只需要询问适配器即可:

      FilmRecord film = getItem(position);
      

      【讨论】:

      • 是的,我正在从数据库中读取数据。那我应该如何避免这个问题呢?
      • 你好 ramdroid。我已经按照建议修改了代码,添加了使用 ViewHolder 的 @Adil 建议。两者都对代码进行了出色的改进。但是随着这些变化,我还有另一个问题。一旦我向下浏览列表,我就会得到重复的列表项。例如。第 5 行和第 6 行的内容与第 0 行相同。有什么想法我哪里出错了吗?
      【解决方案5】:

      检查此链接 http://www.javacodegeeks.com/2012/06/android-smooth-list-scrolling.html

      并将其添加到 Activity OnCreate() 方法中

      protected void onCreate(Bundle savedInstanceState) {
      
          //StrictMode for smooth list scroll
          StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectDiskReads().detectDiskWrites().detectNetwork().penaltyLog().build());
      
          super.onCreate(savedInstanceState);
      
          setContentView(R.layout.activity_main);
      
          /*----- 
              ListView 
              Custom Adapter set data....
          ------*/
      

      }

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-02-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-01-18
        相关资源
        最近更新 更多