2013-04-08 155 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

相关问题