我的应用程序的ListView
有15行。如果有新的搜索查询,我将adapter
设置为null
并清除Allvideos
变量并使用
`new ArrayList();
当用户点击最后一行"更多结果"我将项目添加到Allvideos
。但是在我的应用程序中进行了一些搜索并将这些项目添加到列表后,我的应用程序速度很慢,当我尝试向上滚动时崩溃。这是我的Adapter
public class VideosAdapter extends BaseAdapter {
// The list of videos to display
public static List<Video> videos;
// An inflator to use when creating rows
private LayoutInflater mInflater;
private Context context;
/**
* @param context this is the context that the list will be shown in - used to create new list rows
* @param videos this is a list of videos to display
*/
public VideosAdapter(Context context, List<Video> videos) {
VideosAdapter.videos = videos;
this.mInflater = LayoutInflater.from(context);
this.context = context;
}
@Override
public int getCount() {
return videos.size();
}
@Override
public Object getItem(int position) {
return videos.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
public Object getItem(int position) {
return videos.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final Video video = videos.get(position);
ViewHolder viewHolder;
if(video.getTitle()==null && video.getDuration()==-1)
{
convertView = mInflater.inflate(R.layout.more_results, null);
View thumbnail = convertView.findViewById(R.id.thumbnail);
thumbnail.setVisibility(View.INVISIBLE);
return convertView;
}
//animation = AnimationUtils.loadAnimation(context, R.anim.push_up_in);
// If convertView wasn't null it means we have already set it to our list_item_user_video so no need to do it again
else if(convertView == null){
convertView = mInflater.inflate(R.layout.list_item_user_video, null);
viewHolder = new ViewHolder();
viewHolder.thumb = (UrlImageView) convertView.findViewById(R.id.list_image);
viewHolder.duration=(TextView) convertView.findViewById(R.id.duration);
viewHolder.title = (TextView) convertView.findViewById(R.id.userVideoTitleTextView);
convertView.setTag(viewHolder);
}
else{
// we've just avoided calling findViewById() on resource everytime
// just use the viewHolder
viewHolder = (ViewHolder) convertView.getTag();
}
// We are using a custom imageview so that we can load images using urls
// For further explanation see: http://blog.blundell-apps.com/imageview-with-loading-spinner/
//TextView size=(TextView) convertView.findViewById(R.id.size);
int durationmin=video.getDuration()/60;
int durationsec=video.getDuration()%60;
if(durationsec<10) viewHolder.duration.setText(durationmin+":0"+durationsec);
else{
viewHolder.duration.setText(durationmin+":"+durationsec);
}
// thumb image
// Get a single video from our list
// Set the image for the list item
viewHolder.thumb.setImageDrawable(video.getThumbUrl());
// Set the title for the list item
//ytapi.com düzelene kadar böyle kalacak.
//size.setText(df.format(MainActivity.getSizeOf(MainActivity.getDownloadUrl(videoid)))+" MMB");
viewHolder.title.setText(video.getTitle());
/*animation.setDuration(1000);
convertView.startAnimation(animation);
animation = null;*/
return convertView;
}
我将项目添加到列表并使用此代码设置适配器。
if(Allvideos.isEmpty())
{
Allvideos=videos;
}
else
{
//Remove extra more results row
Allvideos.remove(Allvideos.size()-1);
for(int i=0;i<videos.size();i++)
{
Allvideos.add(videos.get(i));
}
}
VideosAdapter adapter = new VideosAdapter(getContext(), Allvideos);
//adapter.notifyDataSetChanged();
setAdapter(adapter);
我的logcat是这样的。
08-22 15:53:40.557: E/InputEventReceiver(619): Exception dispatching input event.
08-22 15:53:40.657: E/AndroidRuntime(619): FATAL EXCEPTION: main
08-22 15:53:40.657: E/AndroidRuntime(619): java.lang.NullPointerException
08-22 15:53:40.657: E/AndroidRuntime(619): at com.skymaster.tut.ui.adapter.VideosAdapter.getView(VideosAdapter.java:108)
08-22 15:53:40.657: E/AndroidRuntime(619): at android.widget.AbsListView.obtainView(AbsListView.java:2255)
08-22 15:53:40.657: E/AndroidRuntime(619): at android.widget.ListView.makeAndAddView(ListView.java:1769)
08-22 15:53:40.657: E/AndroidRuntime(619): at android.widget.ListView.fillUp(ListView.java:706)
08-22 15:53:40.657: E/AndroidRuntime(619): at android.widget.ListView.fillGap(ListView.java:645)
08-22 15:53:40.657: E/AndroidRuntime(619): at android.widget.AbsListView.trackMotionScroll(AbsListView.java:5040)
08-22 15:53:40.657: E/AndroidRuntime(619): at android.widget.AbsListView.scrollIfNeeded(AbsListView.java:3197)
08-22 15:53:40.657: E/AndroidRuntime(619): at android.widget.AbsListView.onTouchEvent(AbsListView.java:3471)
08-22 15:53:40.657: E/AndroidRuntime(619): at android.view.View.dispatchTouchEvent(View.java:7127)
08-22 15:53:40.657: E/AndroidRuntime(619): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2170)
08-22 15:53:40.657: E/AndroidRuntime(619): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1905)
08-22 15:53:40.657: E/AndroidRuntime(619): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2176)
08-22 15:53:40.657: E/AndroidRuntime(619): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1919)
08-22 15:53:40.657: E/AndroidRuntime(619): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2176)
08-22 15:53:40.657: E/AndroidRuntime(619): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1919)
08-22 15:53:40.657: E/AndroidRuntime(619): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2176)
08-22 15:53:40.657: E/AndroidRuntime(619): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1919)
08-22 15:53:40.657: E/AndroidRuntime(619): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2176)
08-22 15:53:40.657: E/AndroidRuntime(619): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1919)
08-22 15:53:40.657: E/AndroidRuntime(619): at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1925)
08-22 15:53:40.657: E/AndroidRuntime(619): at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1379)
08-22 15:53:40.657: E/AndroidRuntime(619): at android.app.Activity.dispatchTouchEvent(Activity.java:2396)
08-22 15:53:40.657: E/AndroidRuntime(619): at android.support.v7.app.ActionBarActivityDelegateICS$WindowCallbackWrapper.dispatchTouchEvent(ActionBarActivityDelegateICS.java:268)
08-22 15:53:40.657: E/AndroidRuntime(619): at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1873)
08-22 15:53:40.657: E/AndroidRuntime(619): at android.view.View.dispatchPointerEvent(View.java:7307)
08-22 15:53:40.657: E/AndroidRuntime(619): at android.view.ViewRootImpl.deliverPointerEvent(ViewRootImpl.java:3174)
08-22 15:53:40.657: E/AndroidRuntime(619): at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:3119)
08-22 15:53:40.657: E/AndroidRuntime(619): at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:4155)
08-22 15:53:40.657: E/AndroidRuntime(619): at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:4134)
08-22 15:53:40.657: E/AndroidRuntime(619): at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:4226)
08-22 15:53:40.657: E/AndroidRuntime(619): at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:171)
08-22 15:53:40.657: E/AndroidRuntime(619): at android.view.InputEventReceiver.nativeConsumeBatchedInputEvents(Native Method)
08-22 15:53:40.657: E/AndroidRuntime(619): at android.view.InputEventReceiver.consumeBatchedInputEvents(InputEventReceiver.java:163)
08-22 15:53:40.657: E/AndroidRuntime(619): at android.view.ViewRootImpl.doConsumeBatchedInput(ViewRootImpl.java:4205)
08-22 15:53:40.657: E/AndroidRuntime(619): at android.view.ViewRootImpl$ConsumeBatchedInputRunnable.run(ViewRootImpl.java:4245)
08-22 15:53:40.657: E/AndroidRuntime(619): at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725)
08-22 15:53:40.657: E/AndroidRuntime(619): at android.view.Choreographer.doCallbacks(Choreographer.java:555)
08-22 15:53:40.657: E/AndroidRuntime(619): at android.view.Choreographer.doFrame(Choreographer.java:523)
08-22 15:53:40.657: E/AndroidRuntime(619): at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711)
08-22 15:53:40.657: E/AndroidRuntime(619): at android.os.Handler.handleCallback(Handler.java:615)
08-22 15:53:40.657: E/AndroidRuntime(619): at android.os.Handler.dispatchMessage(Handler.java:92)
08-22 15:53:40.657: E/AndroidRuntime(619): at android.os.Looper.loop(Looper.java:137)
08-22 15:53:40.657: E/AndroidRuntime(619): at android.app.ActivityThread.main(ActivityThread.java:4745)
08-22 15:53:40.657: E/AndroidRuntime(619): at java.lang.reflect.Method.invokeNative(Native Method)
08-22 15:53:40.657: E/AndroidRuntime(619): at java.lang.reflect.Method.invoke(Method.java:511)
08-22 15:53:40.657: E/AndroidRuntime(619): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
08-22 15:53:40.657: E/AndroidRuntime(619): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
08-22 15:53:40.657: E/AndroidRuntime(619): at dalvik.system.NativeStart.main(Native Method)
此行发生错误:java:108 我从站点(video.getDuration())获取持续时间,并在第二类型中使用持续时间,如360秒而不是6分钟。
duration.setText(durationmin+":"+durationsec);
为了平滑滚动,我使用ViewHolder
,但它没有解决我的问题。正如您在我的代码中看到的那样,每行的布局中都有URLIMAGEVIEW
。使用此项目,我从每个行的URL加载不同的图像。在图像加载时,微调器出现,直到加载完成。此外URLIMAGEVIEW
位于另一个Thread
,而不是Thread
。 URLIMAGEVIEW
可能导致错误或导致我的应用速度变慢吗?
答案 0 :(得分:1)
我认为你错过了在某个if convertView.setTag(viewHolder)
中的viewHolder
。因为这个{{1}}是空的。
答案 1 :(得分:1)
为什么要将视频作为静态字段;没有必要,这是一种不好的做法。
此外,在显示列表中的项目时,请考虑延长ArrayAdapter
而不是BaseAdapter
;那样你只需要覆盖getView;而不是getPosition,getCount等。
if(Allvideos.isEmpty())
{
Allvideos=videos;
}
else
{
//Remove extra more results row
Allvideos.remove(Allvideos.size()-1);
请考虑在此处使用页脚,而不是每次都添加和删除最后一项。作为奖励,它使您的getView方法更简单。
for(int i=0;i<videos.size();i++)
{
Allvideos.add(videos.get(i));
您可能需要查看addAll方法。
}
}
VideosAdapter adapter = new VideosAdapter(getContext(), Allvideos);
您不需要每次都重新创建适配器。相反,请执行以下操作:
//fields
private ArrayList<Video> videos;
private ArrayAdapter mAdapter;
private View footer;
protected void onCreate(Bundle savedInstanceState) {
ListView list = findViewById(R.id.list);
footer = getLayoutInflater().inflate(R.layout.more_results, null);
list.addFooterView(footer);
videos = new ArrayList<Video>
mAdapter = new VideosAdapter(this, videos);
list.setAdapter(mAdapter);
}
public addItemsToList(List<Video> items){
videos.addAll(items);
mAdapter.notifyDataSetChanged();
}
作为奖励,页脚始终位于列表的末尾。如果要删除页脚,可以切换页脚的可见性,这也很不错。
关于你的错误;添加页脚时,问题将得到解决。当前问题是由您的moreResults布局引起的。
convertView = mInflater.inflate(R.layout.more_results, null);
View thumbnail = convertView.findViewById(R.id.thumbnail);
thumbnail.setVisibility(View.INVISIBLE);
return convertView;
请注意,如果您的适配器下次尝试回收此视图,则convertView将不为null;但是,这里没有设置标签。因此,发生nullPointerException。
答案 2 :(得分:0)
我在两个文本行上的listview和每行的图像都有同样的问题。我发现问题在于图像的尺寸。虽然文件大小非常低,但尺寸很高(大约1600x1600)。我只是减少了Photoshop中的尺寸(大约512x512),现在滚动没有任何延迟。