我创建了一个自定义列表视图,除了列表不能平滑滚动之外,它工作得很好。它波涛汹涌而且很慢。
这是我填充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;
}
创建自定义列表视图时是否有人遇到类似问题?一如既往的任何帮助将非常感激:)
答案 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....
------*/
}