Android 2.3: Two buttons in Listview with BaseAdapter and OnClickListener

1

MY CASE:

  • I have a fragment (fraArticulos) and its respective Layout (lytarticulos) which contains a listview (lstArticulos).

    fraArticulos.java

    public class fraArticulos extends Fragment {  
        String[] NomProd = {'PC','Teclado','Mouse'};  
        String[] DescProd= {'CPU I7','Kit MS','6 botones'};    
        String[] PrecProd= {'2000.00','80.00','60.00'};    
        String[] StockProd= {'10','50','100'};  
    
        clsAdapArticulos Adapter;  
        ListView miLista;  
    
        @Override  
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {  
        View view= inflater.inflate(R.layout.lytArticulos, container, false);  
        miLista = (ListView) view.findViewById(R.id.lstArticulos);  
        Adapter = new clsAdapArticulos(getActivity(), NomProd, DescProd, PrecProd, StockProd);  
        miLista.setAdapter(Adapter);  
    
        miLista.setOnItemClickListener(new AdapterView.OnItemClickListener() {  
            @Override  
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {  
                // Toast.makeText(getActivity(),"item: "+position,Toast.LENGTH_LONG);  
            }  
        });  
        return view;  
        }  
    }    
    
  • lytarticulos.xml

    <LinearLayout
        android:id="@+id/lnr1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:paddingTop="105dp">
    
        <ListView
            android:id="@+id/lstArticulos"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:headerDividersEnabled="true"
            android:isScrollContainer="true"
            android:nestedScrollingEnabled="true"
            android:clickable="true">
    
    
        </ListView>
    
    </LinearLayout>
    

    2. The listview (lstArticulos) is customized through another layout (itemarticulo) which has 02 ImageButton (btnDetails and btnElegir).

    itemarticle

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:orientation="vertical"
        android:descendantFocusability="blocksDescendants">
    
        <LinearLayout
            android:id="@+id/box_container"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="2dp"
            android:orientation="horizontal" >
    
            <LinearLayout
                android:id="@+id/single_post_circuito_linearbox"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_margin="2dp"
                android:orientation="horizontal"
                android:padding="5dp" >
                <LinearLayout
                    android:orientation="vertical"
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="0.7">
                    <TextView
                        android:layout_width="match_parent"
                        android:text="NomProd"
                        android:id="@+id/lblNP"
                    />
    
                    <TextView
                        android:layout_width="match_parent"
                        android:text="Desc Prod"
                        android:id="@+id/lblDesc"
                    />
                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="Precio  prod"
                        android:id="@+id/lblPrec"
                    >
                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="Stock  prod"
                        android:id="@+id/lblStk"
                    >
                </LinearLayout>
                <LinearLayout
                    android:orientation="vertical"
                    android:layout_width="46dp"
                    android:layout_height="wrap_content"
                    >
    
                    <ImageButton
                        android:id="@+id/btnDetalles"
                        android:layout_height="40dp"
                        android:layout_width="match_parent"
                        android:focusable="false"
                        android:scaleType="fitCenter"
                        app:srcCompat="@drawable/deta" />
    
                    <ImageButton
                        android:id="@+id/btnElegir"
                        android:layout_width="match_parent"
                        android:layout_height="40dp"
                        android:focusable="false"
                        android:scaleType="fitCenter"
                        app:srcCompat="@drawable/eleg" />
    
                </LinearLayout>
            </LinearLayout>
        </LinearLayout>
    </LinearLayout>
    

  • I'm using a BaseAdapter to populate the list (clsAdapArticulos).
    clsAdapArticulos.java

    public class clsAdapArticulos extends BaseAdapter {
        // Declare Variables
        Context context;
        String[] NombreProds;
        String[] DescProds;
        String[] PrecioProds;
        String[] StockProds;
        LayoutInflater inflater;  
    
        public clsAdapArticulos(Context context,
                           String[] cNombreProds,
                           String[] cDescProds ,
                           String[] cPrecioProds,
                           String[] cStockProds) {
            this.context = context;
            this.NombreProds = cNombreProds;
            this.DescProds = cDescProds;
            this.PrecioProds = cPrecioProds;
            this.StockProds = cStockProds;
        }  
    
        @Override
        public int getCount() {
            return NombreProds.length;
        }
    
        @Override
        public Object getItem(int position) {
            return null;
        }  
    
        @Override
        public long getItemId(int position) {
            return 0;
        }  
    
        public View getView(int position, View convertView, ViewGroup parent) {  
    
            TextView xNombreProds;
            TextView xDescProds;
            TextView xPrecioProds;
            TextView xStockProds;
            ImageButton xbDetal,xbElegi;
    
            inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    
            View itemView = inflater.inflate(R.layout.itemarticulo, parent, false);
    
            xNombreProds = (TextView) itemView.findViewById(R.id.lblNP);
            xDescProds = (TextView) itemView.findViewById(R.id.lblDesc);
            xPrecioProds = (TextView) itemView.findViewById(R.id.lblPrec);
            xStockProds = (TextView) itemView.findViewById(R.id.lblStk);
    
            xNombreProds.setText(NombreProds[position]);
            xDescProds.setText(DescProds[position]);
            xPrecioProds.setText(PrecioProds[position]);
            xStockProds.setText(StockProds[position]);
    
            xbDetal = (ImageButton) itemView.findViewById(R.id.btnDetalles);
            xbDetal.setTag(position);
            xbElegi = (ImageButton) itemView.findViewById(R.id.btnElegir);
            xbElegi.setTag(position);
    
            xbDetal.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    // Toast.makeText(context,"presionó detalles",Toast.LENGTH_LONG);
                }
            });  
    
            xbElegi.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    // Toast.makeText(context,"presionó elegir",Toast.LENGTH_LONG);
                }
            });
            return itemView;
        }  
    }
    
  • WHAT WORKS:

  • The adapter fills the listview correctly.
  • The Adapter has a clicklist for each button and works correctly showing a toast (this is easy to do).
  • In the fragment after the setAdapter, the OnItemClick works correctly when I press an element of the list showing another Toast with the position of the item (this is also easy).
  • WHAT I WANT AND DO NOT ACHIEVE:

  • Remove the ToClick from the OnClickListener from the buttons in the Adpater (I already did it).
  • When you press any of the buttons, show me the position of the element, so that you can perform a different action (this programming must be done in fragment and not in the adapter, the problem I do not know how or in what part I should do it) .
  • Help, I have been looking for the solution for 5 days but I have not been able to solve it.

    CLARIFICATION:

      

    I have read almost all the existing articles but none of them has solved the problem. The reason is that many of them are "copy   paste "from others and are not well explained.

        
    asked by Jorny 14.03.2017 в 00:53
    source

    2 answers

    0

    Finally I have been able to find the answer, I hope it serves others:
    1. In the Adapter (clsAdapArticulos)

    BEFORE

            xbDetal.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    // Toast.makeText(context,"presionó detalles",Toast.LENGTH_LONG);
                }
            });  
    
            xbElegi.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    // Toast.makeText(context,"presionó elegir",Toast.LENGTH_LONG);
                }
            });  
    

    AFTER

            xbDetal.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    ((ListView) parent).performItemClick(view, position, 0);
                }
            });  
    
            xbElegi.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    ((ListView) parent).performItemClick(view, position, 0);
                }
            });  
    
  • In the fragment.
  • BEFORE

        miLista.setOnItemClickListener(new AdapterView.OnItemClickListener() {  
            @Override  
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {  
                // Toast.makeText(getActivity(),"item: "+position,Toast.LENGTH_LONG);  
            }  
        });  
    

    AFTER

        miLista.setOnItemClickListener(new AdapterView.OnItemClickListener() {  
            @Override  
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {  
                int viewId = view.getId();
                switch (viewId){
                      case R.id.btnDetalles:
                           //Boton Detalles
                           Toast.makeText(getActivity(),"Boton detalles: "+position,Toast.LENGTH_LONG);                         
                           break;
                      case R.id.btnElegir:
                           //boton Elegir
                           Toast.makeText(getActivity(),"Boton elegir: "+position,Toast.LENGTH_LONG);
                           break;
                      default:
                           //item de la lista
                           Toast.makeText(getActivity(),"Item lista: "+position,Toast.LENGTH_LONG);
                           break;
                }
            }  
        });  
    
        
    answered by 14.03.2017 / 16:53
    source
    0

    You can do it with a listener created by yourself. For example, you have this listener:

    public interface OnItemActionClickListener(){
         void onDetalleClick();
         void onElegirClick();
    }
    

    Then your fragment makes you implement this interface:

    public class fraArticulos extends Fragment implements OnItemActionClickListener{
    ...
    
    @Override
    public void onDetalleClick(){
        //Tu codigo...
    }
    
    @Override
    public void onElegirClick(){
        //Tu codigo...
    }
    
    ...
    
    }
    

    And in the construction of the adapter you pass a reference to this listener that will be the same fragment as it is implemented:

    Adapter = new clsAdapArticulos(getActivity(), NomProd, DescProd, PrecProd, StockProd, this);  
    miLista.setAdapter(Adapter);  
    

    Then in the adapter's constructor:

    public class clsAdapArticulos extends BaseAdapter {
        // Declare Variables
        Context context;
        String[] NombreProds;
        String[] DescProds;
        String[] PrecioProds;
        String[] StockProds;
        LayoutInflater inflater; 
    
        OnItemActionClickListener listener; 
    
        public clsAdapArticulos(Context context,
                           String[] cNombreProds,
                           String[] cDescProds ,
                           String[] cPrecioProds,
                           String[] cStockProds,
                           OnItemActionClickListener listener) {
            this.context = context;
            this.NombreProds = cNombreProds;
            this.DescProds = cDescProds;
            this.PrecioProds = cPrecioProds;
            this.StockProds = cStockProds;
            this.listener = listener;
        } 
    ...
    

    To end up in your adapter you just have to call the event you want from the newly implemented listener:

    public View getView(int position, View convertView, ViewGroup parent) {  
    
            ...
    
            xbDetal.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    listener.onDetalleClick();
                }
            });  
    
            xbElegi.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    listener.onElegirClick();
                }
            });
            return itemView;
        }  
    

    I hope that now if you understand it and can implement it.

    Greetings.

        
    answered by 14.03.2017 в 16:22