簡體   English   中英

我的Listview太慢了。 並在向上滾動時崩潰

[英]My Listview is too slow. and crashes while scrolling up

我有一個具有15行的ListView的應用程序。 如果有要搜索的新查詢,我將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上發生錯誤,我從site(video.getDuration())及其第二種類型獲取持續時間,例如360秒而不是6分鍾。

duration.setText(durationmin+":"+durationsec);  

為了平滑滾動,我使用了ViewHolder但它不能解決我的問題。 如您在我的代碼中URLIMAGEVIEW ,我的布局中每行都有URLIMAGEVIEW 通過此項,我從每行的url加載不同的圖像。 在加載圖像時,出現微調框,直到加載完成。 URLIMAGEVIEW也位於另一個Thread ,而不是ui Thread URLIMAGEVIEW可能是錯誤原因或使我的應用程序運行緩慢嗎?

我認為您錯過了某些if塊中的convertView.setTag(viewHolder) 。因為此viewHolder為null。

為什么將視頻作為靜態字段? 這是沒有必要的,也是一種不好的做法。

另外,在顯示列表中的項目時,請考慮擴展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。

我在兩個文本行和每行圖像上都有一個listview的相同問題。 我發現問題出在圖像的尺寸上。 盡管文件大小非常小,但文件大小卻很高(約1600x1600)。 我只是在Photoshop中減小了尺寸(減小到512x512),現在它滾動時沒有任何滯后。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM