2016-06-18 38 views
2

Ich programmiere eine VR-Android-Anwendung und eine benutzerdefinierte Listview verwenden, um Bilder für den Benutzer anzuzeigen. Die Listenansicht ist aus irgendeinem Grund beim Scrollen unglaublich verzögert. Ich habe mir viele Tutorials angeschaut, wie ich die Listenansicht beschleunigen kann, aber ich kann nicht herausfinden, was ich falsch mache. Ich habe versucht, die Größe der Bildtasten zu verringern, den Scroll-Cache und viele andere Dinge deaktiviert. Hinweis: Ich glaube nicht, dass das Picasso-Problem das Problem ist, denn wenn ich es auszeichne, ist es beim Scrollen immer noch langsam.Android Benutzerdefinierte Listview ist sehr langsam trotz der Verwendung von Best Practices

Meine XML für das benutzerdefinierte Layout ist:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:orientation="horizontal" android:layout_width="match_parent" 
android:layout_height="170dp" 
android:padding="10dp"> 
<ImageButton 
    android:layout_width="fill_parent" 
    android:layout_height="150dp" 
    android:id="@+id/redirect_btn" 
    android:longClickable="false" 
/> 


</LinearLayout> 

Der Code für die benutzerdefinierte Listenansicht ist hier:

public class MyCustomAdapter extends BaseAdapter 
{ 
private Activity activity; 
private String[] listOfVideoNames; 
private String[] listOfVideoTileImageURLs; 
private VrVideoInfo[] listOfVrVideoInfo; 
private Context context; 

private static LayoutInflater inflater = null; 

public MyCustomAdapter(String[] listOfVideoNames, String[] listOfVideoTileImages, VrVideoInfo[] vrList, Activity activity, Context context) { 
    this.listOfVideoNames = listOfVideoNames; 
    listOfVideoTileImageURLs = listOfVideoTileImages; 
    this.context = context; 
    this.activity = activity; 
    listOfVrVideoInfo = vrList; 

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

@Override 
public int getCount() { 
    return listOfVideoNames.length; 
} 

@Override 
public Object getItem (int pos) { 
    return listOfVideoNames[pos]; 
} 

@Override 
public long getItemId(int pos) { 
    return 0; 
    // return 0 if your list items do not have an Id variable 
} 
public class Holder { 
    ImageButton imageButton; 
} 

@Override 
public View getView(final int position, View convertView, ViewGroup parent) { 
    final Holder holder; 
    if(convertView == null) 
    { 
     holder = new Holder(); 
     convertView = inflater.inflate(R.layout.custom_list_layout, parent, false); 
     holder.imageButton = (ImageButton) convertView.findViewById(R.id.redirect_btn); 

     convertView.setTag(holder); 

    } 
    else 
    { 
     holder = (Holder)convertView.getTag(); 
    } 

    Picasso.with(context).load(listOfVideoTileImageURLs[position]) 
    .into(holder.imageButton); 
    holder.imageButton.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 

      Intent intent = new Intent(activity, VideoViewer.class); 
      intent.putExtra("video_title", listOfVideoNames[position]); 
      activity.startActivity(intent); 
     } 
    }); 
    return convertView; 
} 

und für alle Fälle ist es relevant, hier ist das, was die benutzerdefinierte Listenansicht ruft :

public class MenuActivity extends Activity { 

// string adapter that will handle the data of the list view 
MyCustomAdapter adapter; 
String[] vrVideoTitles = null; 

String[] videoTileImageListURLs = null; 
ArrayList<VrVideoInfo> videoInfo; 


@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.menu_activity); 


    videoInfo = getIntent().getParcelableArrayListExtra("rData"); 
    vrVideoTitles = new String[videoInfo.size()]; 
    videoTileImageListURLs = new String[videoInfo.size()]; 




    for (int i = 0; i < videoInfo.size(); i++) { 
     vrVideoTitles[i] = videoInfo.get(i).GetTitle(); 
    } 

    for(int i = 0; i < videoInfo.size(); i++) 
    { 
     videoTileImageListURLs[i] = videoInfo.get(i).GetImageURl(); 
    } 

    VrVideoInfo[] info = videoInfo.toArray(new VrVideoInfo[videoInfo.size()]); 

    //instantiate custom adapter 
    adapter = new MyCustomAdapter(vrVideoTitles,  
    videoTileImageListURLs,info, this, this); 

    //handle listview and assign adapter 
    ListView lView = (ListView) findViewById(R.id.list_container); 
    lView.setOverScrollMode(View.OVER_SCROLL_NEVER); 
    lView.setScrollingCacheEnabled(false); 
    lView.setDrawingCacheEnabled(false); 
    lView.setAdapter(adapter); 
} 



} 

Alle Informationen oder Tipps wären sehr hilfreich und geschätzt.

+0

Sind die Bilder verschiedene Größen? –

+0

@EugeneH Die Bilder haben alle die gleiche Größe. Wenn ich die Picasso-Linie ausdenke, bleibt sie noch immer zurück. –

+0

haben Sie versucht, diese Zeile zu entfernen lView.setDrawingCacheEnabled (false); – NIPHIN

Antwort

0

machen Sie Ihre VIEWHELDER statische, nicht statische innere Klassen haben auch einen Verweis auf ihre enthaltene Klasse und es ist keine Speicher effiziente Implementierung.

+0

: D, schön, bitte fügen Sie einen Kommentar mit Angabe des Grundes für das Downvote. Referenz http://Stackoverflow.com/questions/10864853/when-exactly-is-it-leak-safe-to-use-anonymous-inner-klassen https://developer.android.com/training/improving- Layouts/smooth-scrolling.html – NIPHIN

+0

wird es überhaupt nicht die Leistung verbessern. Wie viele 'Holder'-Objekte erwartest du zu erstellen? Weißt du, wie groß die Bytes in jeder Holder-Instanz sind? Wenn man es "statisch" macht, wird nur eine Referenz für jede "Holder" -Instanz entfernt, BT sollte das OP-Objekt nicht verwenden, da es in 99% Fällen den Code komplexer macht und keine Auswirkungen auf die Performance hat. – pskink

+0

Viewholder-Muster ist verwendet, um teure findviewbyid() - Operation zu vermeiden, so verbessert die Verwendung Halter Muster definitiv Leistung – NIPHIN

0

Ich habe es nach einer Weile herausgefunden. Anscheinend hat ein anderer Praktikant, an dem ich arbeite, eine Bildansicht über die Listenansicht gebracht, und ich habe sie nicht gesehen, weil er sie als transparent festgelegt hat. Mit anderen Worten: Stellen Sie keine Bildansichten über Listenansichten.