ListView - загружать больше элементов с помощью прокрутки

Мне нужна помощь с просмотром списка, который я использую во фрагменте. Приложение считывает данные из API, и мой код работает нормально. Сначала я загружаю 15 элементов, а каждый следующий раз загружаю еще 10 элементов. Однако, если запрос к API возвращает менее 15 элементов, он не работает. Кроме того, приложение дает сбой, когда количество элементов не кратно 15, 25 или 35. Это связано с тем, что я загружаю 10 элементов после первоначальной настройки.

Мне нужно изменить свой код, чтобы он работал с любым количеством элементов списка.

Мой код выглядит следующим образом:

(ListaFragment.java) -> Вот фрагмент списка

    public class ListaFragment extends ListFragment implements OnScrollListener {
    public ListaFragment(){}
    View rootView;

    ListAdapter customAdapter = null;
    ListaLugares listaLugares;    

    // values to pagination
    private View mFooterView;
    private final int AUTOLOAD_THRESHOLD = 4;
    private int MAXIMUM_ITEMS;
    private Handler mHandler;
    private boolean mIsLoading = false;
    private boolean mMoreDataAvailable = true;
    private boolean mWasLoading = false;

    public int ventana = 0;
    public int nInitial;

    private Runnable mAddItemsRunnable = new Runnable() {
        @Override
        public void run() {
            customAdapter.addMoreItems(10);
            mIsLoading = false;

        }
    };


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        rootView = inflater.inflate(R.layout.fragment_lista, container, false);

        if (container != null) {
            container.removeAllViews();
        }

        ((MainActivity) getActivity()).setBar();


        // read number of places of a category
        listaLugares.readNumberOfPlaces();
        // set
        setNumbersOfItems();
        // read the places a insert in a List
        listaLugares.readPlaces(15, ventana, listaLugares.idCategoria);
        //ventana = ventana + 25;

        return rootView;
    }


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        listaLugares = ((ListaLugares)getActivity().getApplicationContext());
    }


    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        final Context context = getActivity();
        mHandler = new Handler();
        customAdapter = new ListAdapter(context, listaLugares.lista);

        mFooterView = LayoutInflater.from(context).inflate(R.layout.loading_view, null);
        getListView().addFooterView(mFooterView, null, false);
        setListAdapter(customAdapter);
        getListView().setOnScrollListener(this);
    }


    public void setNumbersOfItems() {
        if (listaLugares.totalItems > 100) {
            MAXIMUM_ITEMS = 100;
            nInitial = 25;
        } else {
            MAXIMUM_ITEMS = listaLugares.totalItems;
            nInitial = listaLugares.totalItems;
        }
        Log.v("NUMBER OF ITEMS", "Number: " + MAXIMUM_ITEMS + "-"+ nInitial);
    }



    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        super.onListItemClick(l, v, position, id);

        //Intent myIntent = new Intent(getActivity(), DetalleActivity.class);
        //myIntent.putExtra("param_id", appState.lista.get(position).id);
        //getActivity().startActivity(myIntent); 
    }


    @Override
    public void onScroll(AbsListView view, int firstVisibleItem,
                         int visibleItemCount, int totalItemCount) {

         if (!mIsLoading && mMoreDataAvailable) {
             if (totalItemCount >= MAXIMUM_ITEMS) {
                 mMoreDataAvailable = false;
                 getListView().removeFooterView(mFooterView);
             } else if (totalItemCount - AUTOLOAD_THRESHOLD <= firstVisibleItem + visibleItemCount) {
                 ventana = ventana + 10;
                 listaLugares.readPlaces(10, ventana, listaLugares.idCategoria);
                 mIsLoading = true;
                     mHandler.postDelayed(mAddItemsRunnable, 1000);
             }
         }
    }


    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        // Ignore
    }


    @Override
    public void onStart() {
        super.onStart();
        if (mWasLoading) {
            mWasLoading = false;
            mIsLoading = true;
            mHandler.postDelayed(mAddItemsRunnable, 1000);
        }
    }


    @Override
    public void onStop() {
        super.onStop();
        mHandler.removeCallbacks(mAddItemsRunnable);
        mWasLoading = mIsLoading;
        mIsLoading = false;
        ventana = ventana;
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
    }

(ListAdapter.java) -> Метод в классе адаптера для добавления дополнительных элементов.

    public class ListAdapter extends ArrayAdapter<Lugar> {
Context context;
List<Lugar> values;

ListaLugares listaLugares;

private int mCount = 20;


public ListAdapter(Context context, List<Lugar> values) {
    super(context, R.layout.row, values);
    this.context = context;
    this.values = values;
}

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

    LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    row = inflater.inflate(R.layout.row, parent, false);
    TextView firstText = (TextView) row.findViewById(R.id.titulo);
    TextView secondText = (TextView) row.findViewById(R.id.categoria);

    firstText.setText(values.get(position).nombre);
    secondText.setText(values.get(position).categoriaNombre);

    return row;
}


public void addMoreItems(int count) {
    mCount += count;
    notifyDataSetChanged();
}

@Override
public int getCount() {
    return mCount;
}


@Override
public long getItemId(int position) {
    return position;
}

}

person Yeray    schedule 14.01.2014    source источник
comment
Включайте в вопрос только related code, см. sscce.org   -  person albusshin    schedule 14.01.2014
comment
я использую этот benjii.me/2010/08/endless-scrolling -listview-в-android   -  person njzk2    schedule 14.01.2014
comment
Хорошо, я отредактировал код в ListAdapter, но не могу обобщить ListaFragment, потому что весь код важен. Спасибо за предложение ;)   -  person Yeray    schedule 14.01.2014
comment
вы можете проверить ApiDemos, есть хороший пример, который делает это.   -  person Alejandro Cumpa    schedule 14.01.2014


Ответы (1)


Я присоединился к предыдущей отредактированной версии, чтобы увидеть код.

Первый вызов работает, потому что вы начинаете со значения 15 в initiaItems и устанавливаете его в mCount в конструкторе ListAdapter.

public ListAdapter(Context context, List<Lugar> values, int count) {
    super(context, R.layout.row, values);
    this.context = context;
    this.values = values;
    this.mCount = count;
}

Поэтому, когда Android отображает список, он обращается к функции ListAdapter.getCount() и возвращает mCount (15).

Но когда вы прокручиваете, он может вызывать

public void addMoreItems(int count, int idCategoria) {
    appState = ((ListaLugares)getContext().getApplicationContext());
    appState.readPlaces(15, mCount, idCategoria);
    mCount += count;
    notifyDataSetChanged();
}

Если количество элементов, возвращенных appState.readPlaces, неизвестно, почему вы добавляете число в mCount mCount += count;?

Если appState.readPlaces возвращает 14, а count равно 15 при отображении списка, предполагается, что имеется 15+15 элементов, когда их 15+14, поэтому последний элемент рухнет.

mCount должен получить длину от объекта, который хранит данные от вызовов API, в вашем случае я думаю, что это будет appState.lista.

person AlexBcn    schedule 15.01.2014
comment
Я изменил свой код, но не могу решить свою проблему. Мой новый код находится под вопросом. Я следую следующему руководству: informit.com/articles/article.aspx? p=2066699&seqNum=4 - person Yeray; 17.01.2014
comment
Если у нас есть список значений, как насчет return (mCount > values.size()) ? values.size() : mCount вместо return mCount - person hypd09; 17.01.2014