我有一个BaseAdapter,有3种布局,用于将JSONObject放到我的ListView中。适配器getCount()返回应该在ListView上显示的正确项目数,但它只显示第一个项目。
我试图在这里找到对此问题的另一个回应,但我没有找到。
这是我的代码:
public class PerfilInfoAdapter extends BaseAdapter {
public static final int VIEW_TYPE_TITULO = 0;
public static final int VIEW_TYPE_DESCRICAO = 1;
public static final int VIEW_TYPE_KEY_VALUE = 2;
private JSONArray list;
private Activity activity;
private ViewHolder viewHolder;
public PerfilInfoAdapter(Activity activity, JSONArray list) {
this.activity = activity;
this.list = list;
}
protected class ViewHolder {
TextView textViewTitulo;
TextView textViewDescricao;
TextView textViewKey;
TextView textViewValue;
}
@Override
public int getCount() {
Log.d("PerfilInfoAdapter", "Number of items in array: " + Integer.toString(this.list.length()));
return this.list.length();
}
@Override
public JSONObject getItem(int position) {
JSONObject json = null;
try {
json = this.list.getJSONObject(position);
} catch (JSONException e) {
e.printStackTrace();
}
return json;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public int getItemViewType(int position) {
int retorno = -1;
JSONObject json = null;
try {
json = this.list.getJSONObject(position);
if (json.getString("key").equals("Titulo")) {
retorno = VIEW_TYPE_TITULO;
} else if (json.getString("key").equals("Descrição")
|| json.getString("key").equals("Sou")) {
retorno = VIEW_TYPE_DESCRICAO;
} else {
retorno = VIEW_TYPE_KEY_VALUE;
}
} catch (JSONException e) {
e.printStackTrace();
}
return retorno;
}
@Override
public int getViewTypeCount() {
return 3;
}
@Override
public View getView(int position, View container, ViewGroup viewGroup) {
System.out.println("getView " + position + " " + container);
this.viewHolder = null;
int type = this.getItemViewType(position);
if (container == null) {
this.viewHolder = new ViewHolder();
switch (type) {
case VIEW_TYPE_TITULO:
container = this.activity.getLayoutInflater().inflate(
R.layout.perfil_info_full_titulo, viewGroup, false);
this.viewHolder.textViewTitulo = (TextView) container
.findViewById(R.id.perfil_info_full_textViewTitulo);
break;
case VIEW_TYPE_DESCRICAO:
container = this.activity.getLayoutInflater().inflate(
R.layout.perfil_info_full_descricao, viewGroup, false);
this.viewHolder.textViewDescricao = (TextView) container
.findViewById(R.id.perfil_info_full_textVewDescricao);
break;
case VIEW_TYPE_KEY_VALUE:
container = this.activity.getLayoutInflater().inflate(
R.layout.perfil_info_list, viewGroup, false);
this.viewHolder.textViewKey = (TextView) container
.findViewById(R.id.perfil_info_full_chave_valor_textFieldChave);
this.viewHolder.textViewValue = (TextView) container
.findViewById(R.id.perfil_info_full_chave_valor_textFieldValor);
break;
}
container.setTag(this.viewHolder);
} else {
this.viewHolder = (ViewHolder)container.getTag();
}
try {
JSONObject json = this.list.getJSONObject(position);
switch (type) {
case VIEW_TYPE_TITULO:
this.viewHolder.textViewTitulo.setText(json.getString("value"));
break;
case VIEW_TYPE_DESCRICAO:
this.viewHolder.textViewDescricao.setText(json
.getString("value"));
break;
case VIEW_TYPE_KEY_VALUE:
this.viewHolder.textViewKey.setText(json.getString("key"));
this.viewHolder.textViewValue.setText(json.getString("value"));
break;
}
} catch (JSONException e) {
e.printStackTrace();
}
return container;
}
}
这是我的日志返回的内容:
10-26 09:42:30.568:D / PerfilInfoAdapter(17228):中的项目数 阵列:11
另一个重要信息是我的ListView位于另一个GridView中,它有4种不同的视图,gridView工作正常,但不是ListView。
public class PerfilAdapter extends BaseAdapter {
private List<JSONObject> jsonList;
private Activity activity;
private PerfilHelper helper;
private ImageLoader imageLoader;
private ViewHolder viewHolder;
private boolean exibirFull;
public static final int VIEW_TYPE_FOTO_PRINCIPAL = 0;
public static final int VIEW_TYPE_INFO = 1;
public static final int VIEW_TYPE_INFO_LIST = 2;
public static final int VIEW_TYPE_GALERIA = 3;
public PerfilAdapter(Activity activity, List<JSONObject> json, PerfilHelper helper) {
this.activity = activity;
this.helper = helper;
this.jsonList = json;
this.exibirFull = true;
if (!ImageLoader.getInstance().isInited()) {
ImageLoader.getInstance().init(new ImageLoaderConfiguration.Builder(this.activity).build());
}
imageLoader = ImageLoader.getInstance();
}
public void exibirFull(boolean exibir) {
this.exibirFull = exibir;
this.notifyDataSetChanged();
}
@Override
public int getCount() {
return this.jsonList.size();
}
@Override
public Object getItem(int i) {
return this.jsonList.get(i);
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public int getItemViewType(int position) {
int retorno = -1;
if (this.jsonList.get(0).has("foto")) {
if (position == 0) {
retorno = VIEW_TYPE_FOTO_PRINCIPAL;
}
else if (position == 1) {
retorno = VIEW_TYPE_INFO;
}
else if (position == 2) {
if (this.exibirFull) {
retorno = VIEW_TYPE_INFO_LIST;
}
else {
retorno = VIEW_TYPE_GALERIA;
}
}
else {
retorno = VIEW_TYPE_GALERIA;
}
}
else {
if (position == 0) {
retorno = VIEW_TYPE_INFO;
}
else if (position == 1) {
if (this.exibirFull) {
retorno = VIEW_TYPE_INFO_LIST;
}
else {
retorno = VIEW_TYPE_GALERIA;
}
}
else {
retorno = VIEW_TYPE_GALERIA;
}
}
return retorno;
}
@Override
public int getViewTypeCount() {
return 4;
}
public void updateJsonPerfil(List<JSONObject> json) {
this.jsonList = json;
this.notifyDataSetChanged();
}
@Override
public View getView(int i, View container, ViewGroup viewGroup) {
this.viewHolder = null;
int type = this.getItemViewType(i);
if (container == null) {
this.viewHolder = new ViewHolder();
switch (type) {
case VIEW_TYPE_FOTO_PRINCIPAL:
container = this.activity.getLayoutInflater().inflate(R.layout.perfil_foto, viewGroup, false);
this.viewHolder.imageView = (ImageView) container.findViewById(R.id.perfil_foto_imageView);
break;
case VIEW_TYPE_INFO:
container = this.activity.getLayoutInflater().inflate(R.layout.perfil_info, viewGroup, false);
this.viewHolder.textViewApelido = (TextView) container.findViewById(R.id.perfil_info_apelido);
this.viewHolder.textViewCidade = (TextView) container.findViewById(R.id.perfil_info_textVewCidade);
this.viewHolder.textViewDistancia = (TextView) container.findViewById(R.id.perfil_info_textViewDistancia);
break;
case VIEW_TYPE_INFO_LIST:
container = this.activity.getLayoutInflater().inflate(R.layout.perfil_info_list, viewGroup, false);
this.viewHolder.listViewInfo = (ListView) container.findViewById(R.id.perfil_info_list_listView);
break;
case VIEW_TYPE_GALERIA:
container = this.activity.getLayoutInflater().inflate(R.layout.perfil_info, viewGroup, false);
break;
}
container.setTag(this.viewHolder);
}
else {
this.viewHolder = (ViewHolder)container.getTag();
}
if (this.jsonList.size() > 0) {
JSONObject json = this.jsonList.get(i);
try {
if (type == VIEW_TYPE_FOTO_PRINCIPAL) {
JSONObject foto = json.getJSONObject("foto");
this.imageLoader.displayImage(foto.getString("full"), this.viewHolder.imageView);
}
else if (type == VIEW_TYPE_INFO) {
JSONObject perfil = json.getJSONObject("perfil");
this.viewHolder.textViewApelido.setText(perfil.getString("apelido"));
this.viewHolder.textViewCidade.setText(perfil.getString("cidade"));
this.viewHolder.textViewDistancia.setText(perfil.getString("distancia"));
}
else if (type == VIEW_TYPE_INFO_LIST) {
// This is where i use the second ListView
this.viewHolder.listViewInfo.setAdapter(new PerfilInfoAdapter(this.activity, json.getJSONArray("info")));
}
else {
Log.d("PerfilAdapter", "Populando: VIEW_TYPE_GALERIA");
}
} catch (JSONException e) {
e.printStackTrace();
}
}
return container;
}
protected class ViewHolder {
ImageView imageView;
TextView textViewApelido;
TextView textViewCidade;
TextView textViewDistancia;
ListView listViewInfo;
}
}
我尝试将ListView更改为GridView,但问题出在适配器上。
任何人都可以帮助我吗?我很感激!
答案 0 :(得分:1)
您的第一个问题:尝试合并ListView
和GridView
。永远不会永远将一个放在另一个之内。当你注意到时,你会遇到各种各样的问题。第一个大问题是滚动。当可滚动视图嵌入另一个滚动视图并且都滚动相同方向时,Android不喜欢它。来自Android员工的Comical sketch有关此问题。这样做只有在水平滚动而另一个垂直滚动时才可行。
您的下一个重大问题是将ListAdapter
嵌入另一个ListAdapter
。您必须记住,每个位置可以调用getView()
方法3-4次。当你为每个位置嵌入另一个适配器时,它本身将被调用3-4次,而它自己的位置......神圣的性能命中!这有不好的想法写在它上面。
我看到的问题是您的JSONArray
/ List
引用。 PerfilInfoAdapter
维护对用于实例化它的JSONArray
的相同引用...这与PerfilAdapter
List
引用的数据相同。此外,PerfilAdapter
维护着由使用它的人引用的相同列表。这会设置一个危险的引用链,如果您不小心,可能会在修改时导致问题。理想情况下,每个适配器应在List
或JSONArray
实例上保留相同的数据。
总而言之,答案是改变您的设计选择。除了在垂直滚动内需要垂直滚动之外,还有其他方式可以显示数据。如果ListView
不需要滚动,请使用LinearLayout
。如果GridView
不需要滚动,请使用TableLayout
或GridLayout
。或者通过提出不同的UI来完全改变用户体验。
作为旁注,如果您需要完整的JSONArray适配器,请查看Advanced-Adapters。 JSONAdapter将在一周左右发布,可以在Redesign
分支上找到。它的代码完整,只是支持发布的演示应用程序。
答案 1 :(得分:0)
如何正确实现getItem
(不返回null)?
或者我更喜欢
GSON
)ArrayAdapter
而非BaseAdapter
,以便您不必实施所有抽象方法。