2013-04-08 107 views
0

我需要使用getView()方法的自定義適配器的幫助。當適配器在每次像holder.textEpisode.setTextColor()等渲染的getView()方法中創建一個列表時,這會產生沉重的負載,並且列表開始減慢。
請幫我解決這個問題。謝謝!自定義ListView + getView方法

public class myAdapterDouble extends ArrayAdapter<Order> { 

private int[] colorWhite = new int[] { -0x1 }; 
private int[] colors = new int[] { -0x1, -0x242425 }; 
private int[] colorBlack = new int[] { -0x1000000 }; 
private int[] colorTransparent = new int[] { android.R.color.transparent }; 
private LayoutInflater lInflater; 
private ArrayList<Order> data; 
private Order o; 
private DisplayImageOptions options; 
private ImageLoader imageLoader; 
private ImageLoaderConfiguration config; 
private Context ctx; 
private Typeface tf; 

public myAdapterDouble(Context c, int listItem, ArrayList<Order> data) { 
super(c, listItem, data); 
lInflater = LayoutInflater.from(c); 
this.data = data; 
ctx = c; 

tf = Typeface.createFromAsset(ctx.getAssets(), "meiryo.ttc"); 

imageLoader = ImageLoader.getInstance(); 
options = new DisplayImageOptions.Builder() 
     .showStubImage(R.drawable.no_image) 
     .showImageForEmptyUri(R.drawable.no_image).cacheOnDisc() 
     .cacheInMemory().build(); 

config = new ImageLoaderConfiguration.Builder(c.getApplicationContext()) 
     .threadPriority(Thread.NORM_PRIORITY - 2) 
     .memoryCacheSize(2 * 1024 * 1024) // 2 Mb 
     .memoryCacheExtraOptions(100, 100) 
     .denyCacheImageMultipleSizesInMemory() 
     .discCacheFileNameGenerator(new Md5FileNameGenerator()) 
     .tasksProcessingOrder(QueueProcessingType.LIFO).enableLogging() 
     .build(); 
ImageLoader.getInstance().init(config); 
} 

SharedPreferences sharedPref; 
boolean posters, fixFont; 
float headerSize, timeSize, dateSize; 
int imageWSize; 

public View getView(final int position, View convertView, ViewGroup parent) { 

ViewHolder holder = null; 
o = data.get(position); 

sharedPref = PreferenceManager.getDefaultSharedPreferences(ctx); 
posters = sharedPref.getBoolean("poster", true); 
fixFont = sharedPref.getBoolean("fix_font", false); 

if (convertView == null) { 
    convertView = lInflater.inflate(R.layout.double_list_item, null); 
    holder = new ViewHolder(); 
    holder.textName = (TextView) convertView.findViewById(R.id.text); 
    if (fixFont) { 
     try { 
      holder.textName.setTypeface(tf); 
     } catch (Exception e) { 
      Toast.makeText(ctx, e.toString(), Toast.LENGTH_SHORT).show(); 
     } 
    } else { 
     try { 
      holder.textName.setTypeface(Typeface.DEFAULT); 
     } catch (Exception e) { 
      Toast.makeText(ctx, e.toString(), Toast.LENGTH_SHORT).show(); 
     } 
    } 
    holder.textEpisode = (TextView) convertView.findViewById(R.id.text2); 
    holder.img = (ImageView) convertView.findViewById(R.id.image); 

    String width = sharedPref.getString("image_width", "70"); 
    imageWSize = Integer.parseInt(width); // ширина 
    final float scale = getContext().getResources().getDisplayMetrics().density; 
    int px = (int) (imageWSize*scale + 0.5f); 

    holder.img.getLayoutParams().height = LayoutParams.WRAP_CONTENT; 
    holder.img.getLayoutParams().width = px; 
    if(imageWSize == 0) { 
     holder.img.getLayoutParams().width = LayoutParams.WRAP_CONTENT; 
    } 
    holder.img.setPadding(5, 5, 5, 5); 

    convertView.setTag(holder); 
} else { 
    holder = (ViewHolder) convertView.getTag(); 
} 

headerSize = Float.parseFloat(sharedPref.getString("headsize", "20")); 
holder.textName.setTextSize(headerSize); // размер названия 
timeSize = Float.parseFloat(sharedPref.getString("timesize", "15")); 
holder.textEpisode.setTextSize(timeSize); // размер времени 

if (posters) { 
    holder.img.setVisibility(View.VISIBLE); 
    try { 
     imageLoader.displayImage(o.getLink(), holder.img, options); 
    } catch (NullPointerException e) { 
     e.printStackTrace(); 
    } 
} else { 
    holder.img.setVisibility(View.GONE); 
} 

holder.img.setTag(o); 
holder.textName.setText(o.getTextName()); 
holder.textEpisode.setText(o.getTextEpisode()); 
holder.textEpisode.setTextColor(Color.BLACK); 

if (o.getTextEpisode().toString().contains(ctx.getString(R.string.final_ep))) { 
    String finaleColor = sharedPref.getString("finale_color", "1"); 
    if (finaleColor.contains("default")) { 
     holder.textEpisode.setTextColor(Color.parseColor("#2E64FE")); 
    } 
    if (finaleColor.contains("yelow")) { 
     holder.textEpisode.setTextColor(Color.YELLOW); 
    } 
    if (finaleColor.contains("red")) { 
     holder.textEpisode.setTextColor(Color.RED); 
    } 
    if (finaleColor.contains("green")) { 
     holder.textEpisode.setTextColor(Color.GREEN); 
    } 
    if (finaleColor.contains("white")) { 
     holder.textEpisode.setTextColor(Color.WHITE); 
    } 
    if (finaleColor.contains("gray")) { 
     holder.textEpisode.setTextColor(Color.GRAY); 
    }   
} else { 
    holder.textEpisode.setTextColor(Color.parseColor("#2E64FE")); 
} 

String chooseColor = sharedPref.getString("colorList", ""); 
if (chooseColor.contains("white")) { 
    int colorPos = position % colorWhite.length; 
    convertView.setBackgroundColor(colorWhite[colorPos]); 
} 
if (chooseColor.contains("black")) { 
    int colorPos = position % colorBlack.length; 
    convertView.setBackgroundColor(colorBlack[colorPos]); 
    holder.textName.setTextColor(Color.parseColor("#FFFFFF")); 
} 
if (chooseColor.contains("whitegray")) { 
    int colorPos = position % colors.length; 
    convertView.setBackgroundColor(colors[colorPos]); 
} 
if (chooseColor.contains("transparent")) { 
    int colorPos = position % colorTransparent.length; 
    convertView.setBackgroundColor(colorTransparent[colorPos]); 
} 

return convertView; 
} 
+0

這是Listview的行爲,以回收視圖,以節省內存。 Listview實現了大量的回收機制。它會爲當前可見的項目分配內存,所以每次都會調用getView() – Pragnani 2013-04-08 05:35:25

+0

可以以某種方式解決這個問題? – 2013-04-08 05:37:25

+0

您需要使用帶有滾動視圖的LinearLayout,但是當列表太大時它會導致內存問題 – Pragnani 2013-04-08 05:39:20

回答

1

getView()方法將在您每次執行加載下一個項目的滾動時調用。

sharedPref = PreferenceManager.getDefaultSharedPreferences(ctx); 
posters = sharedPref.getBoolean("poster", true); 
fixFont = sharedPref.getBoolean("fix_font", false); 

這應該會減慢滾動,因爲每次需要讀取和解析首選項。

是否已將所有這些首選項加載一次作爲某些變量。

如果仍然不能解決嘗試Method Profiling的問題,請檢查getView方法的Incl%,並查看哪些方法在getView中使用更多的cpu使用。

EDITED

public class myAdapterDouble extends ArrayAdapter<Order> { 
    private int[] colorWhite = new int[] { -0x1 }; 
    private int[] colors = new int[] { -0x1, -0x242425 }; 
    private int[] colorBlack = new int[] { -0x1000000 }; 
    private int[] colorTransparent = new int[] { android.R.color.transparent }; 
    private LayoutInflater lInflater; 
    private ArrayList<Order> data; 
    private Order o; 
    private DisplayImageOptions options; 
    private ImageLoader imageLoader; 
    private ImageLoaderConfiguration config; 
    private Context ctx; 
    private Typeface tf; 


    boolean posters, fixFont; 
    float headerSize, timeSize, dateSize; 
    int imageWSize; 
    private String finaleColor; 
    private String chooseColor; 
    private String final_ep; 

    public myAdapterDouble(Context c, int listItem, ArrayList<Order> data) { 
     super(c, listItem, data); 
     lInflater = LayoutInflater.from(c); 
     this.data = data; 
     ctx = c; 

     tf = Typeface.createFromAsset(ctx.getAssets(), "meiryo.ttc"); 

     imageLoader = ImageLoader.getInstance(); 
     options = new DisplayImageOptions.Builder().showStubImage(R.drawable.no_image).showImageForEmptyUri(R.drawable.no_image).cacheOnDisc().cacheInMemory().build(); 

     config = new ImageLoaderConfiguration.Builder(c.getApplicationContext()).threadPriority(Thread.NORM_PRIORITY - 2).memoryCacheSize(2 * 1024 * 1024) 
       // 2 Mb 
       .memoryCacheExtraOptions(100, 100).denyCacheImageMultipleSizesInMemory().discCacheFileNameGenerator(new Md5FileNameGenerator()).tasksProcessingOrder(QueueProcessingType.LIFO) 
       .enableLogging().build(); 
     ImageLoader.getInstance().init(config); 

     SharedPreferences sharedPref; 

     sharedPref = PreferenceManager.getDefaultSharedPreferences(ctx); 
     posters = sharedPref.getBoolean("poster", true); 
     fixFont = sharedPref.getBoolean("fix_font", false); 

     String width = sharedPref.getString("image_width", "70"); 
     imageWSize = Integer.parseInt(width); // ширина 
     headerSize = Float.parseFloat(sharedPref.getString("headsize", "20")); 
     timeSize = Float.parseFloat(sharedPref.getString("timesize", "15")); 

     finaleColor = sharedPref.getString("finale_color", "1"); 
     chooseColor = sharedPref.getString("colorList", ""); 
     final_ep = ctx.getString(R.string.final_ep); 
    } 

    public View getView(final int position, View convertView, ViewGroup parent) { 

     ViewHolder holder = null; 
     o = data.get(position); 

     if (convertView == null) { 
      convertView = lInflater.inflate(R.layout.double_list_item, null); 
      holder = new ViewHolder(); 
      holder.textName = (TextView) convertView.findViewById(R.id.text); 
      if (fixFont) { 
       try { 
        holder.textName.setTypeface(tf); 
       } 
       catch (Exception e) { 
        Toast.makeText(ctx, e.toString(), Toast.LENGTH_SHORT).show(); 
       } 
      } 
      else { 
       try { 
        holder.textName.setTypeface(Typeface.DEFAULT); 
       } 
       catch (Exception e) { 
        Toast.makeText(ctx, e.toString(), Toast.LENGTH_SHORT).show(); 
       } 
      } 
      holder.textEpisode = (TextView) convertView.findViewById(R.id.text2); 
      holder.img = (ImageView) convertView.findViewById(R.id.image); 


      final float scale = getContext().getResources().getDisplayMetrics().density; 
      int px = (int) (imageWSize * scale + 0.5f); 

      holder.img.getLayoutParams().height = LayoutParams.WRAP_CONTENT; 
      holder.img.getLayoutParams().width = px; 
      if (imageWSize == 0) { 
       holder.img.getLayoutParams().width = LayoutParams.WRAP_CONTENT; 
      } 
      holder.img.setPadding(5, 5, 5, 5); 

      convertView.setTag(holder); 
     } 
     else { 
      holder = (ViewHolder) convertView.getTag(); 
     } 


     holder.textName.setTextSize(headerSize); // размер названия 

     holder.textEpisode.setTextSize(timeSize); // размер времени 

     if (posters) { 
      holder.img.setVisibility(View.VISIBLE); 
      try { 
       imageLoader.displayImage(o.getLink(), holder.img, options); 
      } 
      catch (NullPointerException e) { 
       e.printStackTrace(); 
      } 
     } 
     else { 
      holder.img.setVisibility(View.GONE); 
     } 

     holder.img.setTag(o); 
     holder.textName.setText(o.getTextName()); 
     holder.textEpisode.setText(o.getTextEpisode()); 
     holder.textEpisode.setTextColor(Color.BLACK); 


     if (o.getTextEpisode().toString().contains()) { 

      if (finaleColor.contains("default")) { 
       holder.textEpisode.setTextColor(Color.parseColor("#2E64FE")); 
      } 
      if (finaleColor.contains("yelow")) { 
       holder.textEpisode.setTextColor(Color.YELLOW); 
      } 
      if (finaleColor.contains("red")) { 
       holder.textEpisode.setTextColor(Color.RED); 
      } 
      if (finaleColor.contains("green")) { 
       holder.textEpisode.setTextColor(Color.GREEN); 
      } 
      if (finaleColor.contains("white")) { 
       holder.textEpisode.setTextColor(Color.WHITE); 
      } 
      if (finaleColor.contains("gray")) { 
       holder.textEpisode.setTextColor(Color.GRAY); 
      } 
     } 
     else { 
      holder.textEpisode.setTextColor(Color.parseColor("#2E64FE")); 
     } 


     if (chooseColor.contains("white")) { 
      int colorPos = position % colorWhite.length; 
      convertView.setBackgroundColor(colorWhite[colorPos]); 
     } 
     if (chooseColor.contains("black")) { 
      int colorPos = position % colorBlack.length; 
      convertView.setBackgroundColor(colorBlack[colorPos]); 
      holder.textName.setTextColor(Color.parseColor("#FFFFFF")); 
     } 
     if (chooseColor.contains("whitegray")) { 
      int colorPos = position % colors.length; 
      convertView.setBackgroundColor(colors[colorPos]); 
     } 
     if (chooseColor.contains("transparent")) { 
      int colorPos = position % colorTransparent.length; 
      convertView.setBackgroundColor(colorTransparent[colorPos]); 
     } 

     return convertView; 
    } 
} 
+0

'是否所有這些首選項都作爲一些變量加載一次?「您可以爲此發佈樣本?我是Java的初學者 – 2013-04-08 05:58:33

+0

然後用更新後的代碼更新你的問題。 – 2013-04-08 05:59:35

+0

更新。需要樣本以更好地理解 – 2013-04-08 06:02:33

0

嘗試這樣的,而不是viewholder這完全適用於我。

public View getView(int position, View convertView, ViewGroup parent) { 
View v = convertView; 
sharedPref = PreferenceManager.getDefaultSharedPreferences(ctx); 
posters = sharedPref.getBoolean("poster", true); 
fixFont = sharedPref.getBoolean("fix_font", false); 

if (v == null) { 
    LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    v = vi.inflate(R.layout.double_list_item, null); 
} 

TextView textName = (TextView) v.findViewById(R.id.text); 
if (fixFont){ 
    try { 
     textName.setTypeface(tf); 
    } catch (Exception e) { 
     Toast.makeText(ctx, e.toString(), Toast.LENGTH_SHORT).show(); 
    } 
}else { 
    try { 
     textName.setTypeface(Typeface.DEFAULT); 
    } catch (Exception e) { 
     Toast.makeText(ctx, e.toString(), Toast.LENGTH_SHORT).show(); 
    } 
} 
return super.getView(position, v, parent); 
} 
}; 

我希望這會幫助你。

+0

這是正確的代碼?沒有ViewHolder?我認爲'LayoutInflater vi =(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);'必須在構造函數中調用一次以獲得更好的性能。對? – 2013-04-08 06:14:05

+0

不需要Azat。嘗試一下。如果你沒有得到你想要的答案,然後嘗試在你的構造函數中添加該行,然後讓我知道是否找到任何區別。 – Gunaseelan 2013-04-08 06:28:33

相關問題