在ListView中使用fastScrollEnabled时不滚动平滑

时间:2015-03-01 12:53:44

标签: android listview baseadapter android-viewholder

我在我的应用中使用了listview。我制作了一个自定义适配器并使用了视图设计模式。问题是当我通过平滑地滑动滚动滚动列表视图但是当我通过拖动快速滚动拇指滚动它时它滞后太多。它经常冻结一段时间。我已经检查了我的手机中的其他应用程序,如默认音乐播放器,无论我如何滚动它,列表视图滚动像风。我没有在列表中使用任何imageview,每行只有三个textview。

这是完整的代码:

public class CustomListViewSongs extends BaseAdapter{


    private Context context;

    private ArrayList songs, artist, songduration;


    private static LayoutInflater inflater = null;

    public CustomListViewSongs(Context context, ArrayList songs, ArrayList artist, ArrayList songDuration){
        this.context = context;
        this.songs = songs;
        this.artist = artist;
        this.songduration = songDuration;



    }

    @Override
    public int getCount() {
        return songs.size();
    }

    @Override
    public Object getItem(int position) {
        return songs.get(position);
    }

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



    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        Holder holder;
        inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View rowView = convertView;
        if(rowView == null){
            rowView = inflater.inflate(R.layout.customlistviewsongssinglerow, null);
            holder = new Holder();
            holder.songTitle = (TextView) rowView.findViewById(R.id.songTitle);
            holder.songTitleArtist = (TextView) rowView.findViewById(R.id.songTitleArtist);
            holder.songDuration = (TextView) rowView.findViewById(R.id.songDuration);
            rowView.setTag(holder);
        }else{
            holder = (Holder) rowView.getTag();
        }
        holder.songTitle.setText("" + songs.get(position));
        holder.songTitleArtist.setText("" + artist.get(position));
        long duration = Long.parseLong("" + songduration.get(position));
        int seconds = (int) ((duration / 1000) % 60);
        long minutes = ((duration - seconds) / 1000) / 60;
        if (seconds < 10) {
            holder.songDuration.setText("" + minutes + ":0" + seconds);
        } else {
            holder.songDuration.setText("" + minutes + ":" + seconds);
        }
        return rowView;
    }

    public class Holder {
        TextView songTitle, songTitleArtist, songDuration;
        int position;

    }


}

和listview xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="match_parent"
    android:layout_height="match_parent">
        <ListView
            android:fastScrollEnabled="true"
            android:fastScrollAlwaysVisible="false"
            android:background="@android:color/transparent"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/listView"/>
</RelativeLayout>

并称之为:

    public class f1 extends Fragment {

    private MainActivity f = new MainActivity();
    private ListView lv;
    private View view;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        view = inflater.inflate(R.layout.f1, container, false);
        populate();
        return view;
    }
    private void populate() {
        lv = (ListView) view.findViewById(R.id.listView);
        lv.setAdapter(new CustomListViewSongs(getActivity(), f.songs, f.artist, f.songsDuration));
    }

}

2 个答案:

答案 0 :(得分:1)

您可以尝试移动此行

inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

rowView == null之内。由于意见被回收,它被不必要地被召唤了太多次,并且它被使用的唯一地方就是在条件下。

不确定这是否是主要问题。

您还可以通过将默认值设置为textView并注释掉计算来测试您的歌曲持续时间计算是否导致延迟。如果你看到了改进,那么你应该在后台线程中进行计算。

修改:注意到您的视图持有者模式应该实现为static class。用这个替换你的代码

static class Holder {
        TextView songTitle, songTitleArtist, songDuration;
        int position;
}

答案 1 :(得分:0)

在列表视图中为每个 调用getView()方法。看来你在getView()方法中进行了大量的视图通信和处理。重构此方法可获得更流畅的性能。尝试最小化在方法中执行的代码,因为向下滚动系统可能需要更多内存并在之前的视图中运行垃圾清理,因此当您上下移动getView()时再次调用 。另外你为什么View rowView = convertView;convertView是旧视图,必须重复,如果,以避免性能问题。有关详细信息,请查看here