Как увеличить ListFragment с помощью пользовательского ArrayAdapter?

Как увеличить ListFragment с помощью пользовательского ArrayAdapter? У меня два класса «Владелец и Автомобиль». Пользователь будет искать владельца, и он отобразит одного или нескольких владельцев с помощью ListFragments. Кроме того, если пользователь нажмет на владельца, он должен отобразить подробный список автомобилей, которыми владеет владелец. Я создал следующие классы/вспомогательные классы (CarDetail и OwnerDetail — эти два класса расширяют ListFragment, People Extensions FragmentActivity, настраиваемый адаптер CarAdapter и OwnerAdapter, CarAsyncTask и OwnerAsyncTask AsyncTasks и Login, которые расширяют активность). Класс входа позволяет пользователю войти в систему и найти владельца. Когда пользователь входит в систему и выполняет поиск, один или несколько владельцев должны отображаться в верхней части макета. Тем не менее, я не смог заставить его отображаться. Вот мои коды:

//Обновлено 30 июля в 10:50. Я обновил OwnerDetail onActivityCreated, чтобы использовать OwnerActivityAdapter. Однако при установке TextView для держателя возникает исключение. См. исключение внизу.

Для простоты я покажу только часть текста.

//Car Class
public class Car {
    private String _make;
    private String _model;
    private String _year;
public Car(String make, String model, String year)
    {
      this._make = make;
      this._model  = model;
      this._year = year;
    }
}
//Owner Class
public class Owner {

    private String _firstName;
    private String _lastName;
    private String _carId;
    private Car _car;
public Owner(String lName, String fName, String cId, Car car)
    {
         this._lastName = lName;
         this._firstName  = fName;
         this._carId = cId;
         this._car = car;
    }
}


package com.mb.carlovers;

import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
//Car Detail 
public class CarDetail extends ListFragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.customize_layout,container,false);
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        String[] myCars = {};
        super.onActivityCreated(savedInstanceState);
        ArrayAdapter<String> carAdapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_activated_1, myCars);
    setListAdapter(carAdapter);
    }
   }

//OnwerDetail class
public class OwnerDetail extends ListFragment {
@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        return inflater.inflate(R.layout.customize_layout,container, false);
    }
    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
   //Updated on 07/30 @10:50 AM
  //Change this class to use the OwnerAsyncTask()

    OnwerAsyncTask asynTask = new OnwerAsyncTask();
    List<Owner> lt = null;
    try {
        lt = asynTask.execute("").get();
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (ExecutionException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    Owner myOwners[] = lt.toArray(new Owner[lt.size()]);
    super.onActivityCreated(savedInstanceState);
    OwnerAdapter ownerAdapter = new OwnerAdapter(getActivity(),android.R.layout.simple_list_item_activated_1 , myOwners);
    setListAdapter(ownerAdapter);
}

//People where the new Fragment should be created
public class People extends FragmentActivity implements OnClickListener, OnItemSelectedListener {
  private Button search;
  private EditText etSearchBy, etSearchByID;
  private Spinner spOption;
  private String selectedOption = null;
  private TextView tvErrorMessage;
    @Override
    protected void onCreate(Bundle arg0) {
        super.onCreate(arg0);
        setContentView(R.layout.people);
        InitializeVariables();
    }

    private void InitializeVariables()
    {
        etSearchBy = (EditText) this.findViewById(R.id.etByLastName);
        etSearchByID = (EditText) this.findViewById(R.id.etCarID);
        spOption = (Spinner) this.findViewById(R.id.spOption);
        search = (Button) this.findViewById(R.id.bSearch);
        search.setOnClickListener(this);
        tvErrorMessage = (TextView) this.findViewById(R.id.tvErrorMessage);
        ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,R.array.spOptions, android.R.layout.simple_spinner_dropdown_item);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spOption.setAdapter(adapter);
        spOption.setOnItemSelectedListener(this);

    }
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
    }

     @Override
        protected void onPause() {
            super.onPause();
        }

    @Override
    public void onClick(View v) {
        String searchByName = etSearchBy.getText().toString();
        String searchById = etSearchByID.getText().toString();
       if(selectedOption == null || selectedOption == "All")
       {
           if(searchByName.matches("") || searchById.matches(""))
           {
               tvErrorMessage.setText("You must select a last name and car id");
           } else
           {

           }

       } else if(selectedOption == "Name")
       {
           if(!searchByName.matches(""))
           {
                         try
                         {
                           **//Here is the List of information that I need to inflate the fragment with.**
               OnwerAsyncTask ownerAsyncTask = new OnwerAsyncTask();
                      List<Owner> owner = ownerAsyncTask.execute("").get();
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
           } else
           {
               tvErrorMessage.setText("You must enter the last name of the owner.");
           }

       } else if (selectedOption == "ID") 
       {

           if(!searchById.matches(""))
           {
              String st = null;
              String d = st;
           } else
           {
               tvErrorMessage.setText("You must enter the car id that you'd like to search.");
           }
       }
    }

//Owner Adapter – (The Car Adapter looks similar to this except the variables name are different.)
public class OwnerAdapter extends ArrayAdapter<Owner> {

    private Context context;
    private int layoutResourceId;
    private Owner data[] = null;

    public OwnerAdapter(Context context, int resource, int textViewResourceId,Owner[] data) {
        super(context, resource, textViewResourceId, data);
        this.context = context;
        this.layoutResourceId = resource;
        this.data = data;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View row = convertView;
        OwnerHolder holder = null;

        if(row == null)
        {
            LayoutInflater inflater = ((Activity)context).getLayoutInflater();
            row = inflater.inflate(layoutResourceId, parent, false);
            holder = new OwnerHolder();
            holder.tvFirstName = (TextView) row.findViewById(R.id.tvFirstName);
            holder.tvLastName = (TextView) row.findViewById(R.id.tvLastName);
            holder.tvCarId = (TextView) row.findViewById(R.id.tvCarID);
            row.setTag(holder);
        } else
        {
            holder = (OwnerHolder) row.getTag();
        }


        Owner item = data[position];

        **//Updated on 07/30 @10:50 AM
        // Below is where I am getting the exception**
        holder.tvFirstName.setText(item.getFirstName().toString());
        holder.tvLastName.setText(item.getLastName().toString());
        holder.tvCarId.setText(item.getCarId().toString());

        return row;
    }

    static class OwnerHolder
    {
      TextView tvFirstName;
      TextView tvLastName;
      TextView tvCarId;
    }
}

//Owner AsyncTask –(CarAsyncTask is also similar)

public class OnwerAsyncTask extends AsyncTask<String, Void, List<Owner>> {

    private List<Owner> items = null;
    @Override
    protected List<Owner> doInBackground(String... params) {

        try
        {
            items = new ArrayList<Owner>();
            items.add(new Owner("John", "Smith", "1"));
            items.add(new Owner("Samantha", "Right", "2"));
            items.add(new Owner("Regie", "Miller", "3"));
            items.add(new Owner("Mark", "Adam", "4"));

        } catch(Exception ex)
        {
            ex.toString();
        }
        return items;
    }

    @Override
    protected void onPostExecute(List<Owner> result) {
        // TODO Auto-generated method stub
        super.onPostExecute(result);
    }

}

//My customize Layout for the listfragment
<?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:orientation="vertical" >

    <ListView
        android:id="@id/android:list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
    </ListView>

     <TextView
        android:id="@id/android:empty"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="No record to be displayed." />


</LinearLayout>

//Обновлено 30.07.10:50 //Вот исключение

07-30 14:18:15.155: E/AndroidRuntime(864): НЕИСПРАВНОЕ ИСКЛЮЧЕНИЕ: main 07-30 14:18:15.155: E/AndroidRuntime(864): java.lang.NullPointerException 07-30 14:18:15.155: E/AndroidRuntime(864): в com.mb.carlovers.adapter.OwnerAdapter.getView(OwnerAdapter.java:48) 07-30 14:18:15.155: E/AndroidRuntime(864): в android.widget.AbsListView.obtainView (AbsListView.java:2033) 07-30 14:18:15.155: E/AndroidRuntime(864): в android.widget.ListView.onMeasure(ListView.java:1127) 07-30 14:18:15.155: E/AndroidRuntime (864): в android.view.View.measure(View.java:12603) 07-30 14:18:15.155: E/AndroidRuntime(864): в android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4677) 07-30 14:18:15.155: E/AndroidRuntime(864): в android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1369) 07-30 14:18:15.155: E/AndroidRuntime(864): в android. widget.LinearLayout.measureVertical(LinearLayout.java:660) 07-30 14:18:15.155: E/AndroidRuntime(864): в android.widget.LinearLayout.onMeasure(LinearLay out.java:553) 07-30 14:18:15.155: E/AndroidRuntime(864): в android.view.View.measure(View.java:12603) 07-30 14:18:15.155: E/AndroidRuntime( 864): в android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4677) 07-30 14:18:15.155: E/AndroidRuntime(864): в android.widget.FrameLayout.onMeasure(FrameLayout.java:293) 07 -30 14:18:15.155: E/AndroidRuntime(864): в android.view.View.measure(View.java:12603) 07-30 14:18:15.155: E/AndroidRuntime(864): в android.view .ViewGroup.measureChildWithMargins(ViewGroup.java:4677) 07-30 14:18:15.155: E/AndroidRuntime(864): в android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1369)


person Gagouche    schedule 30.07.2013    source источник
comment
Первое, что нужно отметить, вы даже никогда не используете свой собственный адаптер. Вы создаете экземпляры ArrayAdapter в обоих ListFragments.   -  person btse    schedule 30.07.2013
comment
Если бы я использовал пользовательский адаптер во фрагменте списка, не выводил бы он автоматически список владельцев, когда кто-то входит в приложение? Что я хотел сделать, так это загрузить приложение без отображения на обоих фрагментах (именно поэтому я использовал этот пустой ArrayAdapter‹String›). Как только пользователь выполнит поиск, я отобразил бы одного или нескольких владельцев. Я пытаюсь научиться использовать Fragment. Я уже некоторое время с этим борюсь.   -  person Gagouche    schedule 30.07.2013
comment
Нисколько. Так же, как вы уже делаете, вы должны передать пустой массив в качестве аргумента данных. Затем при необходимости добавьте данные в массив и вызовите adapter.notifyDataSetChanged().   -  person btse    schedule 30.07.2013


Ответы (1)


@btse на высоте! Вы можете просто отправить пустой список items пользовательскому адаптеру, а затем вызвать notifyDataSetChanged() на onPostExecute вашего AsyncTask. Android обрабатывает заполнение вашего ListFragment после этого вызова.

Вы даже можете разместить сообщение типа «Пожалуйста, найдите владельца», когда адаптер пуст (ссылка здесь) в вашем xml:

<TextView android:id="@id/android:empty"
           android:layout_width="match_parent"
           android:layout_height="match_parent"
           android:background="#FF0000"
           android:text="Please search owner"/>

если вы не хотите оставлять это поле пустым.

Удачи!

person CodeMonkey    schedule 30.07.2013
comment
Я действительно сбит с толку, потому что я звонил и получал список владельцев из своей асинхронной задачи, когда пользователь что-то искал. Затем я собирался передать его в качестве аргумента фрагменту и получить в файле Oncreate. Если бы я вызывал notifyDataSetChange() в onPostEecute, мне все равно пришлось бы передавать данные в ListFragment, потому что я не вызываю asynckTask напрямую из ListFragment. Я думаю, мне нужно еще немного прочитать об этом. Особенно отправка объекта из FragmentActivity в FragmentList - person Gagouche; 30.07.2013
comment
Аааа ок. Без представления о том, как работает ваше приложение, трудно дать более конкретный ответ. Исходя из вашего комментария, я так понимаю, что фрагмент не создается при поиске? В противном случае, если фрагмент был создан и пользователь выполнил поиск, вы можете предоставить метод во фрагменте, который повторно связывает пользовательский адаптер с новым items, полученным из AsyncTask. Это помогает? - person CodeMonkey; 30.07.2013
comment
Я просто играю с фрагментами. Цель состоит в том, чтобы позволить пользователю войти в систему, используя имя пользователя и пароль. После входа пользователя в систему справа появляется линейный макет с некоторыми параметрами поиска. С левой стороны есть два фрагмента. Верхний фрагмент отобразит список владельцев. Однако список владельцев будет отображаться только тогда и только тогда, когда есть один или несколько владельцев, отвечающих критериям поиска. Когда пользователь нажимает на владельца в верхнем фрагменте, он отображает список автомобилей, которыми он владеет, в левом нижнем фрагменте. - person Gagouche; 30.07.2013