自定义列表视图滚动不顺畅

时间:2012-02-20 09:46:23

标签: android listview custom-lists

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

这是我填充listview的代码:

@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;
    }

创建自定义列表视图时是否有人遇到类似问题?一如既往的任何帮助将非常感激:)

5 个答案:

答案 0 :(得分:5)

您需要使用ViewHolder方法。

因为通过id查找View也需要时间来执行。

使用ViewHolder方法,您可以通过缓存视图来最小化在查找按ID时创建的负载:)

Here是一个很好的教程,如何做到这一点。

编辑:

ViewHolder的做法是:

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

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

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

您必须仅在View 4次充气,但findViewById()在调用getView()时每次都会被称为 (通常在{{1}时滚动)。

快乐的编码!

答案 1 :(得分:1)

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

答案 2 :(得分:0)

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

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

使用数据库时,您应该在onCreate期间将数据加载到适配器中,可能就是这样(但是使用之前的listview布局等)。

@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);

答案 3 :(得分:0)

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

答案 4 :(得分:0)

检查此链接 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....
    ------*/

}