0

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

这是完整的代码:

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;

    }


}

和列表视图 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));
    }

}
4

2 回答 2

1

你可以试试移动这条线

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

里面的时候rowView == null。由于视图正在被回收,它被不必要地调用了太多次,并且它被使用的唯一地方是在 if 条件内。

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

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

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

static class Holder {
        TextView songTitle, songTitleArtist, songDuration;
        int position;
}
于 2015-03-01T13:35:04.417 回答
0

正在为列表视图中的每个 项目调用 getView() 方法。您似乎在 getView() 方法中进行了很多视图膨胀和处理。重构此方法以获得更流畅的性能。尝试最小化方法中正在执行的代码,因为当您向下滚动时,系统可能需要更多内存并在以前的视图中运行垃圾清理,因此当您向上和向下移动时,会再次调用 getView() 。再加上你为什么View rowView = convertView;?这convertView是必须尽可能重用的旧视图以避免性能问题。欲了解更多信息,请查看此处

于 2015-03-01T17:08:27.777 回答