My list is currently implemented with Header and Footer .

Code:

 //Header objects bookDetailsObjects.setDate("16-янв-2105, 15:50"); bookDetailsObjects.setFromTo("TSE - IST"); bookDetailsObjects.setPNR("284TZ8"); bookDetailsObjects.setValidUntil("03-Мар 2016 23:59"); bookDetailsObjects.setRoute("Москва - Станбул"); bookDetailsObjects.setDepartDate("25-Мар 2016 12:30"); bookDetailsObjects.setFlightClass("Econom"); bookDetailsObjects.setStatus(2); View header = getLayoutInflater().inflate(R.layout.book_details_layout_item, listView, false); TextView mFromTo = (TextView) header.findViewById(R.id.tvFromTo); TextView mBookDate = (TextView) header.findViewById(R.id.tvBookDate); TextView mPNR = (TextView) header.findViewById(R.id.tvPNR); TextView mValidUntil = (TextView)header.findViewById(R.id.tvValidUntil); TextView mRoute = (TextView)header.findViewById(R.id.tvRoute); TextView mDepartDate = (TextView)header.findViewById(R.id.tvDepartDate); TextView mClass = (TextView)header.findViewById(R.id.tvClass); TextView mStatus = (TextView)header.findViewById(R.id.tvStatus); mFromTo.setText(bookDetailsObjects.getFromTo()); mBookDate.setText(bookDetailsObjects.getDate()); mPNR.setText(bookDetailsObjects.getPNR()); mValidUntil.setText(bookDetailsObjects.getValidUntil()); mRoute.setText(bookDetailsObjects.getRoute()); mDepartDate.setText(bookDetailsObjects.getDepartDate()); mClass.setText(bookDetailsObjects.getFlightClass()); switch(bookDetailsObjects.getStatus()) { case 2: mStatus.setText(getString(R.string.status_canceled)); break; case 0: mStatus.setText(getString(R.string.status_booked)); break; case 1: mStatus.setText(getString(R.string.status_buyed)); break; default: break; } //End of Header Objects //Passengers objects passengersObjects.setPassGroup(0); passengersObjects.setName("Иванов Иван"); passengersObjects.setBirthDate("14.01.1992"); passengersObjects.setGender("Мужской"); passengersObjects.setAdultTickPrice(15000); passengersObjects.setChildTickPrice(15000); passengersObjects.setInfTickPrice(15000); for (int i = 0; i < 5; i++){ passItems.add(passengersObjects); } //End Passengers objects //Footer objects bookDetailsObjects.setTotalPrice(45000); View footer = getLayoutInflater().inflate(R.layout.book_layout_price_buttons, listView, false); TextView mTotalPrice = (TextView) footer.findViewById(R.id.tvTotalPrice); Button mCancel = (Button) footer.findViewById(R.id.btnDetCancel); mCancel.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { ToastUtils.ToastShort(getApplicationContext(), "Отменено"); } }); Button mBuy = (Button) footer.findViewById(R.id.btnDetBuy); mBuy.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { ToastUtils.ToastShort(getApplicationContext(), "Выкуплено"); } }); mTotalPrice.setText(bookDetailsObjects.getTotalPrice() + "РУБ"); listView.addHeaderView(header); listView.addFooterView(footer); listView.setAdapter(new PassengersDetailAdapter(getApplicationContext(), R.layout.book_layout_pass_items, passItems)); } 

Adapter:

 public class PassengersDetailAdapter extends ArrayAdapter<PassengersObjects> { private int resource; private LayoutInflater inflater; private Context context; static Resources r; public PassengersDetailAdapter(Context ctx, int rsc, List<PassengersObjects> objects) { super(ctx, rsc, objects); resource = rsc; inflater = LayoutInflater.from(ctx); context = ctx; } @Override public View getView(int position, View convertView, ViewGroup parent) { convertView = inflater.inflate(resource, null); PassengersObjects passengersObjects = getItem(position); TextView mName = (TextView)convertView.findViewById(R.id.tvFullName); TextView mGender = (TextView)convertView.findViewById(R.id.tvGender); TextView mBirthDate = (TextView)convertView.findViewById(R.id.tvBirthDate); TextView mTickPrice = (TextView)convertView.findViewById(R.id.tvTickPrice); mName.setText(passengersObjects.getName()); mGender.setText(passengersObjects.getGender()); mBirthDate.setText(passengersObjects.getBirthDate()); switch(passengersObjects.getPassGroup()) { case 0: mTickPrice.setText(passengersObjects.getAdultTickPrice() + "KZT"); break; case 1: mTickPrice.setText(passengersObjects.getChildTickPrice() + "KZT"); break; case 2: mTickPrice.setText(passengersObjects.getInfTickPrice() + "KZT"); break; default: break; } return convertView; } } 

It looks like this:

enter image description here

That is, as I need. But I need them all to be in the same PassengersDetailAdapter , and I just can’t figure out how to implement this, it's a mess in my head. Tell me please!

  • one
    This is done by overriding the getItemViewType() method. Example - pavlofff
  • In your case, when it is passed to this method that the position is on the first element, output the header, when on the last footer, for all the others - intermediate items. - pavlofff

1 answer 1

Do not suffer from ListView . Redo everything on RecyclerView . There it is done like this :

According to the position of the element, we define its type and, depending on this, we load certain markup and display it:

 //метод, в коем вы должны в зависимости от позиции элемента возвращать //её тип в виде числа, кое потом используется в onCreateViewHolder для загрузки разметки //и в onBindViewHolder для наполнения её данными @Override public int getItemViewType(int position) { if (position == 0) { return 0; } else { return 1; } } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { RecyclerView.ViewHolder vh; View itemLayoutView; //загружаем разметку в зависимости от типа и возвращаем //нужный холдер switch (viewType) { case 0: itemLayoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.zero_type_layout, parent, false); vh = new HolderZeroType(itemLayoutView); break; case 1: itemLayoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.first_type_layout, parent, false); vh = new HolderFirstType(itemLayoutView); break; } return vh; } @Override public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) { switch (this.getItemViewType(position)) { case 0: HolderZeroType zero = (HolderZeroType) holder; //наполняем данными разметку для нулевого типа break; case 1: HolderFirstType first = (HolderFirstType) holder; //наполняем данными разметку для нулевого типа break; } } public static class HolderFirstType extends RecyclerView.ViewHolder { ... public ViewHolderText(View v) { super(v); ... } } public static class HolderZeroType extends RecyclerView.ViewHolder { ... public ViewHolderText(View v) { super(v); ... } } 
  • In ListView this is done in almost the same way - pavlofff
  • @pavlofff, IMHO in RecyclerView all this is more convenient) Well, there are no idle types like headers and there are no situations like in the question of how to transfer them to the adapter) And listeners of clicks from outside the adapter are not assigned to the elements, which also eliminates many possible problems. Well, without a ViewHolder adapter to RecyclerView does not write, which also eliminates the need to figure out how to do this for ListVeiw . =) - YuriySPb
  • @YuriySPb, Sorry, but how to check the last position? - DevOma
  • @Omuradil, the length of the list with the data minus one ... - YuriySPb
  • long ago also encountered such problems, implemented through RecyclerView, over time the wrapper github.com/vivchar/RendererRecyclerViewAdapter became blind - Vitaly