1

Its my first post here but i am reading this Q&A for years and I always find an answer, but this time i cannot find it, or i cannot combine multiple answers with my problem. I hope you can help.

So I have fragment which overrides 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;
    }

Then I have method where I set my data

    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");
    }

In that method I am calling my Adapter so i can use my listview layout

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;
    }

}

But for some reason i am getting errors when trying to access tv. It is always null.

I think its something with views that are created/getted, and I am creating/getting some parent view in higher hierarchy. I have tried to debug it but dont know how to use those IDs in debug mode. Well not how to use it, but how to compare it so I can see is it right view.

Please help :)

I did it like this in this edit but nothing. Is it because i am using swipe views and I am getting wrong view in the first?

This is my sve_bacve_item and it has textview. I am kind 1 step forward with @Raghunandan solution but now I have problem with convertin String to holder. I am trying to resolve that.

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

Veki
  • 117
  • 2
  • 9
  • Why is iv == null? Maybe is dummy question but isn't he suppose to inflate R.layout.sve_bacve? – Veki Mar 27 '14 at 18:40
  • you inflate when its null and you need to initialize views when you inflate the layout. read http://stackoverflow.com/questions/11945563/how-listviews-recycling-mechanism-works – Raghunandan Mar 27 '14 at 18:46
  • please post R.layout.sve_bacve_item – Spidy Mar 27 '14 at 19:27
  • @Veki you inflate `sve_bacve.xml` in fragment and you inflate the ame layout in getView of adapter – Raghunandan Mar 27 '14 at 19:50

2 Answers2

0

Use a ViewHolder for perofrmance.

public static ViewHolder
{
    TextView tv;
}

Change to

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;
    }

Change getView to

@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;
}

Also you mention

This is my sve_bacve_item and it has textview

So change

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

to

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

Edit:

Your NPE was because you inflated the wrong layout. I got confused the first time.

Also you have commented this

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

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

remove the comment

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

And do check this to understand ViewHolder pattern to understand why you need it.

A ViewHolder object stores each of the component views inside the tag field of the Layout, so you can immediately access them without the need to look them up repeatedly.

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

and also check

How ListView's recycling mechanism works

Community
  • 1
  • 1
Raghunandan
  • 132,755
  • 26
  • 225
  • 256
  • Yeah i did it and now it works, but it lefted me confused because of that. Thank you guys very much – Veki Mar 27 '14 at 20:04
  • I'm not sure I see the point in using a ViewHolder. Just adds extra for no reason – Spidy Mar 27 '14 at 20:08
  • @spidy may be for just a textview but it does help – Raghunandan Mar 27 '14 at 20:10
  • oh this comment was because of trying to do that with android.R.layout.simple_item_list_1, but then i had 2 cases so i commented one. But this is active always. I will read this smooth-scrolling and that mechanism once more. Thank you – Veki Mar 27 '14 at 20:25
0

I'm guessing your layout doesn't have the TextView defined because your code should look like the following:

@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;
}

And your custom layout should have a text view defined somewhere in your layout file like so.

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

UPDATE

Ok it looks like your layout file looks fine. You still do not need to create a TextView the way you were trying. You can simply findView. One thing I noticed, your inflate call is using the wrong layout (sve_bacve not sve_bacve_item), that is why it is unable to find the text view.

This line:

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

Should be:

convertView = (View) mInflater.inflate(R.layout.sve_bacve_item,parent,false);
Spidy
  • 39,723
  • 15
  • 65
  • 83
  • Omg, maybe I am crazy, but this looks pretty dummyto me. I have changed @Raghunandan 's just into sve_bacve_item and now it works. But then why did I put my layout in adapter super class? I thought i am calling view, where my list view is, and then i am calling from that listview my item layout. – Veki Mar 27 '14 at 19:59
  • Technically you could hand 0 to the super class since you are overriding the getView. If you hadn't overridden getView, the array adapter base class would have used the resource you passed in. Just one of the nuances of subclassing ArrayAdapter. – Spidy Mar 27 '14 at 20:07
  • Oh, now i get it. I didnt think of it in that way that I will override this layout that I already passed in. Thank you very very much – Veki Mar 27 '14 at 20:14