0

I have a ListView with a custom adapter that extends BaseAdapter. When a user clicks on a row, I'd like to replace the whole layout by another (two different xml items). I've searched around for a solution, but couldn't find anything that worked in my case. Here's my code :

  private class ProductListViewAdapter extends BaseAdapter implements Filterable {

    private static final int PRODUCT_ITEM_ID = 9999;
    private ValueFilter valueFilter;

    private int selectedItem = -1;


    @Override
    public int getCount() {
        if (mBookedProducts != null)
            return mBookedProducts.size();
        else
            return 1;
    }

    @Override
    public Object getItem(int position) {
        return position;
    }

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

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

        if(mBookedProducts != null) {

            if(selectedItem != position)
                return getProductView(mBookedProducts.get(position), convertView, position);
            else
                return getProductAnswerView(position, convertView);
        }
        else
            return getPlaceHolderItem(convertView);


    }


    private View getProductAnswerView(int position, View convertView) {

        View view = LayoutInflater.from(getActivity()).inflate(R.layout.booked_product_answer_item, null);


        Button noButton = (Button) view.findViewById(R.id.noButton);
        noButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

            }
        });

        Button yesButton = (Button) view.findViewById(R.id.yesButton);
        yesButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
            //Accept Booking
                Toast.makeText(getActivity(),"Réservation acceptée !", Toast.LENGTH_SHORT).show();
            }
        });


        return view;
    }


    private View getProductView(final BookedProduct bookedProduct, final View convertView, final int position) {

        View view = convertView;

        if(convertView == null || convertView.getId() != PRODUCT_ITEM_ID) {
            view = LayoutInflater.from(getActivity()).inflate(R.layout.booked_product_item, null);
        }

        view.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                selectedItem = position;
                mBookedProductsListView.getAdapter().getView(position, view, mBookedProductsListView);
                mBookedProductsListViewAdapter.notifyDataSetInvalidated();
            }
        });

        TextView productName1 = (TextView) view.findViewById(R.id.productName1);
        productName1.setText(bookedProduct.getName1().toUpperCase());

        TextView productName2 = (TextView) view.findViewById(R.id.productName2);
        productName2.setText(bookedProduct.getName2().toUpperCase());

        TextView userName = (TextView) view.findViewById(R.id.customerName);
        userName.setText(bookedProduct.getCustomerFirstName() + " " + bookedProduct.getCustomerLastName());

        ImageView triangleImage = (ImageView) view.findViewById(R.id.triangleImage);
        switch (bookedProduct.getState()){
            case (-1) :
                triangleImage.setImageResource(R.drawable.trianglered);
                break;
            case 0:
                triangleImage.setImageResource(R.drawable.triangleorange);
                break;
            case 1 :
                triangleImage.setImageResource(R.drawable.trianglegreen);
                break;
        }
        return view;
    }

    private View getPlaceHolderItem(View view) {
        view = LayoutInflater.from(getActivity()).inflate(R.layout.product_placeholder, null);

        TextView placeHolderTV = (TextView) view.findViewById(R.id.placeHolderTV);
        placeHolderTV.setText("Aucune réservation en cours");

        return view;
    }

}

}

The layout is not redrawn on user click. As you can see, I try to redraw the view as specified here : How can I update a single row in a ListView?

I'm almost sure I'm missing something, but I can't find what.

Thank you for your help.

Community
  • 1
  • 1

3 Answers3

0

try to override getViewTypeCount()

@Override
public int getViewTypeCount() {
    // TODO Auto-generated method stub

            return 3;  // number of layout that getview inflate
}

from the developer android

Returns the number of types of Views that will be created by getView(int, View, ViewGroup). Each type represents a set of views that can be converted in getView(int, View, ViewGroup). If the adapter always returns the same type of View for all items, this method should return 1.

olele
  • 69
  • 7
0

I would create a view for the item like this: a RelativeLayout or FrameLayout, with all 3 views in it, only one visible at a time. In bindView() I would add a condition and show one, hide the other 2 (on click handler).

Yar
  • 4,543
  • 2
  • 35
  • 42
  • Yes, but in my case the layout is quite complicated. Plus, when the user clicks another layout appears, if the user clicks again in the latest, radio buttons appear. So it appeared to me, that my solution would be cleaner. Thanks for your suggestion though. – Standaa - Remember Monica Jun 25 '14 at 15:36
0

Update : Ok, i found the answer. I thought calling getView would be enough to reload the view. It's not, at least on KitKat(4.4.3). Calling adapter.notifyDataSetInvalidated() solved my problem.

I updated the code with my latest changes.