【问题标题】:Android fragment + custom listviewAndroid片段+自定义列表视图
【发布时间】:2014-03-28 04:35:29
【问题描述】:

这是我在这里的第一篇文章,但我多年来一直在阅读这个问答,我总是能找到答案,但这次我找不到它,或者我无法将多个答案与我的问题结合起来。我希望你能帮忙。

所以我有覆盖 onCreateView 的片段

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        db  = new WineryDatabaseAdapter(getActivity());
        bacveList = db.getBacve();

        v = inflater.inflate(R.layout.sve_bacve, container, false);
        Log.v("onCreateView", "oncreateview");
        return v;
    }

然后我就有了设置数据的方法

    public void getBacveItems(){
        ArrayAdapter<Bacve> ad = new BacveListAdapter(getActivity(), bacveList);
        lv = (ListView) v.findViewById(R.id.listSveBacve);
        lv.setAdapter(ad);
        lv.setOnItemClickListener(this);
        Log.v("getBacveItems", "getBacveItems");
    }

在那个方法中我调用了我的适配器,所以我可以使用我的列表视图布局

public class BacveListAdapter extends ArrayAdapter<Bacve>{

    List<Bacve> bacve;
    Context c;
    String[] values = new String[] { "prva","druga" };

    public BacveListAdapter(Context c,List<Bacve> l){

        //super(c,R.layout.sve_bacve_item,l);
        super(c,R.layout.sve_bacve_item,l);
        Log.v("BacveListAdapter", "BacveListAdapter");
        this.bacve = l;
        this.c = c;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // TODO Auto-generated method stub
    View iv = convertView;
    TextView tv;
    if (iv == null){
        iv = (View)((LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.sve_bacve,parent,false);
        tv = new TextView(c);
    }
    else{
    Bacve bacva = bacve.get(position);
    tv = (TextView) iv.findViewById(R.id.textNazivBacve);
    tv.setText(bacva.getIme());
    }
    return iv;
    }

}

但由于某种原因,我在尝试访问电视时遇到了错误。它始终为空。

我认为它与创建/获取的视图有关,并且我正在创建/获取更高层次结构中的一些父视图。我试图调试它,但不知道如何在调试模式下使用这些 ID。好吧不是如何使用它,而是如何比较它,以便我看到它是否正确。

请帮忙:)

我在这次编辑中这样做了,但没有。是因为我使用的是滑动视图,而我一开始就看错了吗?

这是我的 sve_bacve_item,它有 textview。 我对@Raghunandan 解决方案很友好,但现在我在将字符串转换为持有人时遇到了问题。我正在努力解决这个问题。

<?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">

<TextView
    android:id="@+id/textNazivBacve"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:layout_marginLeft="15dp"
    android:layout_marginTop="15dp"
    android:layout_toRightOf="@+id/bacveIcon"
    android:text="@string/BacveNaziv"
    android:textAppearance="?android:attr/textAppearanceLarge" />

<ImageView
    android:id="@+id/bacveIcon"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_alignTop="@+id/textNazivBacve"
    android:adjustViewBounds="true"
    android:contentDescription="@string/Bacve"
    android:maxHeight="120dp"
    android:maxWidth="120dp"
    android:src="@drawable/bacve_item" />

</RelativeLayout>

BR

【问题讨论】:

  • 为什么 iv == null?也许是个愚蠢的问题,但他不应该膨胀 R.layout.sve_bacve 吗?
  • 当它为空时你会膨胀,当你膨胀布局时你需要初始化视图。阅读stackoverflow.com/questions/11945563/…
  • 请发布 R.layout.sve_bacve_item
  • @Veki 你在片段中膨胀 sve_bacve.xml 并且你在适配器的 getView 中膨胀 ame 布局

标签: android android-fragments


【解决方案1】:

使用ViewHolder 来提高性能。

public static ViewHolder
{
    TextView tv;
}

改成

LayoutInflater mInflater;
public BacveListAdapter(Context c,List<Bacve> l){

        //super(c,R.layout.sve_bacve_item,l);
        super(c,R.layout.sve_bacve_item,l);
        mInflater = LayoutInflater.from(c); 
        this.bacve = l;
        this.c = c;
    }

getView更改为

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

    ViewHolder holder;

    if (convertView == null){ 
    convertView = (View) mInflater.inflate(R.layout.sve_bacve,parent,false);
    holder = new ViewHolder();
    holder.tv = (TextView) convertView.findViewById(R.id.textNazivBacve);
    convertView.setTag(holder);
    }
    else
    {
      holder = (ViewHolder) convertView.getTag();             
    }
    Bacve bacva = bacve.get(position);
    holder.tv.setText(bacva.getIme());

    return convertView;
}

你也提到

这是我的 sve_bacve_item,它有 textview

所以改变

 convertView = (View) mInflater.inflate(R.layout.sve_bacve,parent,false);

 convertView = (View) mInflater.inflate(R.layout.sve_bacve_item,parent,false);

编辑:

您的 NPE 是因为您夸大了错误的布局。我第一次弄糊涂了。

你也评论过这个

public BacveListAdapter(Context c,List<Bacve> l){

    //super(c,R.layout.sve_bacve_item,l);

删除评论

public BacveListAdapter(Context c,List<Bacve> l){
   super(c,R.layout.sve_bacve_item,l); 

并检查此以了解 ViewHolder 模式以了解您为什么需要它。

ViewHolder 对象将每个组件视图存储在标签内 布局的字段,因此您可以立即访问它们而无需 需要反复查找。

http://developer.android.com/training/improving-layouts/smooth-scrolling.html

还要检查

How ListView's recycling mechanism works

【讨论】:

  • 是的,我做到了,现在它可以工作了,但它让我感到困惑。非常感谢你们
  • 我不确定我是否明白使用 ViewHolder 的意义。只是无缘无故地添加额外的
  • @spidy 可能只是一个文本视图,但它确实有帮助
  • 哦,这条评论是因为试图用 android.R.layout.simple_item_list_1 来做这件事,但后来我有 2 个案例,所以我评论了一个。但这始终处于活动状态。我将再次阅读这个平滑滚动和那个机制。谢谢
【解决方案2】:

我猜你的布局没有定义 TextView,因为你的代码应该如下所示:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
   if (convertView == null) {
    convertView = (View)((LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.sve_bacve_item,parent,false);
   }

   TextView tv = (TextView)convertView.findViewById(R.id.textNazivBacve);
   Bacve bacva = bacve.get(position);
   tv.setText(bacva.getIme());

   return iv;
}

您的自定义布局应该在布局文件中的某处定义一个文本视图,如下所示。

<TextView android:id="@+id/textNazivBacve"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="Hello, I am a TextView" />

更新

好的,您的布局文件看起来不错。您仍然不需要按照您尝试的方式创建 TextView。你可以简单地findView。我注意到一件事,您的 inflate 调用使用了错误的布局(sve_bacve 不是 sve_bacve_item),这就是它无法找到文本视图的原因。

这一行:

convertView = (View) mInflater.inflate(R.layout.sve_bacve,parent,false);

应该是:

convertView = (View) mInflater.inflate(R.layout.sve_bacve_item,parent,false);

【讨论】:

  • 天啊,也许我疯了,但这对我来说看起来很愚蠢。我已将 @Raghunandan 更改为 sve_bacve_item ,现在它可以工作了。但是为什么我把我的布局放在适配器超类中呢?我以为我正在调用视图,我的列表视图在哪里,然后我从该列表视图调用我的项目布局。
  • 从技术上讲,您可以将 0 交给超类,因为您正在覆盖 getView。如果您没有覆盖 getView,数组适配器基类将使用您传入的资源。这只是子类化 ArrayAdapter 的细微差别之一。
  • 哦,现在我明白了。没想到会覆盖这个已经传入的布局,非常感谢
猜你喜欢
  • 1970-01-01
  • 2013-06-26
  • 2015-07-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多