我尝试制作一个包含每行视图的列表视图。此视图包含2个textviews和1个gridview,即2列。在每一列中,我使用的基本布局由2个textviews组成。
这是在gridview的每个块中使用的基本布局的预览。
这是它的xml; - 第一视图 -
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/listview_item">
<TextView
android:layout_width="220dp"
android:layout_height="wrap_content"
android:textSize="18dp"
android:text="Item Name"
android:id="@+id/list_item"
android:maxLines="1"
android:layout_marginLeft="5dp"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Price"
android:textSize="18dp"
android:id="@+id/item_price"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_marginRight="5dp"/>
</RelativeLayout>
这是我的第二个视图,其中包含2个textview和1个gridview。
这里是它的xml; - 第二视图 -
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/listview_item"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="40dp"
android:text="Kategori"
android:id="@+id/categories_title_list_layout"/>
<GridView
android:layout_width="match_parent"
android:layout_height="0dp"
android:id="@+id/gridView_list_layout"
android:numColumns="2"
android:layout_weight="1"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Not: Lorem ipsum dolor sit amet.."
android:textSize="18dp"
android:id="@+id/categories_note"/>
</LinearLayout>
这是我最后的观点; - 第三视图 -
这个listview的每一行都是我的第二个视图的形状,它形成了第一个视图。
这是我的适配器创建此视图。 对于第一个视图,我使用此适配器;
public class ItemListAdapter extends BaseAdapter {
private Context context;
private ArrayList<Item> items;
public ItemListAdapter(Context context, ArrayList<Item> items) {
super();
this.context = context;
this.items = items;
}
public int getCount() {
return items.size();
}
public Object getItem(int i) {
return items.get(i);
}
public long getItemId(int i) {
return i;
}
public View getView(final int i, View view, ViewGroup viewGroup) {
ViewHolder holder;
if(view == null) {
holder = new ViewHolder();
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.listview_item_content, null);
holder.title = (TextView) view.findViewById(R.id.list_item);
holder.price = (TextView) view.findViewById(R.id.item_price);
view.setTag(holder);
}
holder = (ViewHolder) view.getTag();
Typeface face=Typeface.createFromAsset(context.getAssets(), "fonts/roboto.ttf");
holder.title.setTypeface(face, Typeface.BOLD);
holder.title.setText(items.get(i).getName());
holder.title.setTextColor(Color.parseColor(Shop.getInstance().getItemGridTextColor()));
holder.price.setText(Global.getLocalizedPriceStringByLocale(Shop.getLocale(), items.get(i).getPrice()));
holder.price.setTextColor(Color.parseColor(Shop.getInstance().getItemGridTextColor()));
return view;
}
public class ViewHolder {
public TextView title;
public TextView price;
}
}
(此适配器获取项目的标题和价格,并将它们放在第一个视图中。)
创建第二个视图的第二个适配器就在这里;
public class CategoryListAdapter extends BaseAdapter {
private Context context;
//private ArrayList<Item> items;
private ArrayList<Category> currentCategory;
public CategoryListAdapter(Context context, ArrayList<Category> category) {
super();
this.context = context;
currentCategory = category;
}
public int getCount() {
return currentCategory.size();
}
public Object getItem(int i) {
return currentCategory.get(i);
}
public long getItemId(int i) {
return i;
}
public View getView(final int i, View view, ViewGroup viewGroup) {
ViewHolder holder;
if (view == null) {
holder = new ViewHolder();
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.grid_list_layout, null);
holder.title = (TextView) view.findViewById(R.id.categories_title_list_layout);
holder.gridView = (GridView) view.findViewById(R.id.gridView_list_layout);
holder.note = (TextView) view.findViewById(R.id.categories_note);
view.setTag(holder);
}
holder = (ViewHolder) view.getTag();
Typeface face = Typeface.createFromAsset(context.getAssets(), "fonts/roboto.ttf");
holder.title.setTypeface(face, Typeface.BOLD);
if(currentCategory.get(i).getName().equals("")){
holder.title.setText("Diğer");
}else{
holder.title.setText(currentCategory.get(i).getName());
}
holder.title.setTextColor(Color.parseColor(Shop.getInstance().getItemGridTextColor()));
holder.note.setText(currentCategory.get(i).getDeepNote());
holder.note.setTextColor(Color.parseColor(Shop.getInstance().getItemGridTextColor()));
holder.gridView.setAdapter(new ItemListAdapter(context, currentCategory.get(i).getItems()));
holder.gridView.setBackgroundColor(Color.parseColor(Shop.getInstance().getItemGridBackgroundColor()));
holder.gridView.getBackground().setAlpha(180);
return view;
}
public class ViewHolder {
public TextView title;
public GridView gridView;
public TextView note;
}
}
我使用此适配器来创建ListView。
这是我的问题。这工作真的很慢。我的意思是ListView会冻结片刻,然后在我尝试向下移动时向下滑动。 关于GridView的高度还有另一个问题。我的GridView的高度是wrap_content,但它的行为不像wrap_content。它显示更大或更小的GridView。
例如;在“Diğer”标题下应该有一个GridView,它只包含1个项目,但是它无法显示完整的文本。在“AdetÜrünler”下,应该有190件商品,但它只能看到其中的20件。
这些是我的问题。对不起我的编码。如果你无法理解我的代码,请问我。 谢谢你的帮助。
答案 0 :(得分:1)
这个答案不会给你一个明确的解决方案,不是因为我不愿意,而是因为它不可能(甚至更难,不仅仅是查看你的代码,而是非常了解它)。但根据我的经验,我可以告诉你,由于直接引用的对象,这些内存泄漏并不会发生 - 你声明的对象(并继续引用另一个类/对象)依赖于许多其他类等等,并且可能由于对您的任何实例的错误处理而导致内存泄漏,同时引用其他实例。
调试内存泄漏通常是一项非常艰苦的工作,不仅仅是因为正如我上面所述,它有时并不直接依赖于您所声明的内容,而且因为找到解决方案可能并不是一件容易的事。您可以做的最好的事情就是您似乎正在做的事情:DDMS + HPROF。我不知道你有多少知识,但虽然它不是一种通用的方法,this link帮助我找到了代码中的内存泄漏。
虽然看起来微不足道,但调试这类事情的最佳方法是逐步删除代码的一部分(总体而言,意味着使用其他类的实例)并查看HPROF报告的更改方式。
答案 1 :(得分:0)
据我了解你的问题,在滚动屏幕截图中显示的列表时效果不佳?
您的问题的解决方案需要您重写适配器和布局。您的性能问题是由于您使用的相当大的列表项(例如,包含190个项目的单个列表项中的网格),必须在滚动列表期间加载,以及列表项的相对较低的可重用性。
此外,我不想使用观看者。
要摆脱网格,您可以使用包含“标题”,“注释”和其间的单个网格行的对象列表(或如下所示的包装器)。你必须覆盖一些适配器方法,在一个列表视图中使用多个视图类型(如下所示)。
也许您还需要更多代码,将模型映射到新列表中,但毕竟,您的表现应该恢复正常。
我所知道的唯一缺点(并且没有快速解决方案)是由于单个列表项中的高度不同,整个列表的滚动条有时会显示奇怪的行为(例如:滚动条滚动条指示符在滚动期间的高度变化)< / p>
<强>包装强>
public class ListItemWrapper {
ListItemType type;
Object content;
public ListItemWrapper(ListItemType type, Object content) {
this.type = type;
this.content = content;
}
public enum ListItemType { Title,Note, Content;}
}
<强> ListAdapter 强>
public class ListAdapter extends ArrayAdapter<ListItemWrapper> {
private LayoutInflater inflater;
public ListAdapter(Context context, int resource) {
super(context, resource);
inflater = LayoutInflater.from(context);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ListItemWrapper item = getItem(position);
switch (item.type) {
case Content: return getViewForGridRow((GridRowContent)item.content, convertView);
case Note: return getViewForNote((String)item.content, convertView);
case Title: return getViewForTitle((String) item.content, convertView);
}
return convertView; //this case should never happen
}
private View getViewForTitle(String content, View convertView) {
if (convertView == null) {
//TODO inflate a new view for the title
convertView = inflater.inflate(R.layout.titleRowLayout, null);
}
//TODO set textview value for the title
return convertView;
}
private View getViewForNote(String content, View convertView) {
if (convertView == null) {
//TODO inflate a new view for the note
convertView = inflater.inflate(R.layout.noteRowLayout, null);
}
//TODO set textview value for the note
return convertView;
}
private View getViewForGridRow(GridRowContent item, View convertView) {
if (convertView == null) {
//TODO inflate a new view for a single grid row
convertView = inflater.inflate(R.layout.gridRowLayout, null);
}
//TODO set values of the grid row (e.g. textview items)
return convertView;
}
@Override
public int getItemViewType(int position) {
return getItem(position).type.ordinal();
}
@Override
public int getViewTypeCount() {
return ListItemType.values().length;
}
}
我简化了模型的部分,但我希望你能明白这一点。
正如您所看到的,我不使用自定义BaseAdapter,因为arrayadapter已经管理了我的集合。我只需要告诉列表,有不同的项目视图类型以及集合中的哪个项目使用哪种视图类型。
此外,不需要使用任何持有者,因为所有持有和管理不同视图的工作已经由适配器完成 - 例如如果给定的convertView尚未在适配器中缓存,我们只需要膨胀视图。
使用这种方式应该可以提高内存效率,并且性能应该提高,因为只需要在一个步骤中填充更少的视图。
我希望这有帮助,
基督教
修改强>
无法解释中心消失的网格视图,但这不应该再发生了