Search code examples
javaandroidonclicklistener

Android : How to get a reference of a button defined in resource XML and not in Activity XML


Basically I am trying to code a onClickListener for a button in MainActivity.java .

This Button is defined in a resource file : main_resource.xml inside a ListView and not in activity_main.xml.

I am getting the error :

Trying to define a onClick Listener on null item.

Button btn = (Button) findViewById(R.id.mybutton);

btn.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        myFancyMethod(v);
    }
});

Here is my main_resource.xml :

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    android:id="@+id/relativeLayout1"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:padding="5dip">
    <TextView
        android:layout_height="wrap_content"
        android:text="TextView"
        android:layout_width="wrap_content"
        android:id="@+id/ridedetails"
        android:layout_marginLeft="2dip">
    </TextView>

    <EditText
        android:layout_height="wrap_content"
        android:hint="Quote Price"
        android:layout_width="wrap_content"
        android:id="@+id/PriceQuotation"
        android:layout_below="@+id/ridedetails"
        android:layout_marginLeft="2dip">
    </EditText>

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignTop="@+id/PriceQuotation"
        android:layout_marginStart="61dp"
        android:layout_toEndOf="@+id/PriceQuotation"
        android:text="Button" />


</RelativeLayout>

Here is my activity_main.xml :

<?xml version="1.0" encoding="utf-8"?>  
<android.support.v4.widget.SwipeRefreshLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/myrefresh"
    android:focusable="false"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">


    <android.support.v4.widget.DrawerLayout
        android:id="@+id/drawer_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true"
        tools:openDrawer="start">
    
        <include
            layout="@layout/app_bar_home"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    
        <android.support.design.widget.NavigationView
            android:id="@+id/nav_view"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_gravity="start"
            android:fitsSystemWindows="true"
            app:headerLayout="@layout/nav_header_home"
            app:menu="@menu/activity_home_drawer" />
    
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            tools:context=".PreviousRide"
            >
    
            <ListView
                android:id="@+id/incomingrides"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_marginStart="30dp"
                android:layout_marginTop="80dp"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent"></ListView>
    
        </LinearLayout>
    
    </android.support.v4.widget.DrawerLayout>
</android.support.v4.widget.SwipeRefreshLayout>

Here I am not using any Custom Adapter Class : I am injecting the data into my list view using the following ArrayAdapter code written in onRefresh() of Swipe Refresh Widget ::

final ArrayAdapter<String > adapter=new ArrayAdapter<String>(getApplicationContext(), 
                                 R.layout.home_resource, R.id.ridedetails, allNames);
l1.setAdapter(adapter);

// L1 is the listView Reference

Solution

  • You have to create custom class for adapter Here is sample code for adapter.

     public class MyAdapter extends ArrayAdapter<String> {
                private int resourceId;
                private List<String> sites = null;
                private Context context;
    
                public MyAdapter(Context context, int resource, List<String> objects) {
                    super(context, resource, objects);
                    this.context = context;
                    this.resourceId = resource;
                    this.sites = objects;
                }
    
                @Override
                public String getItem(int position) {
                    return sites.get(position);
                }
    
                @Override
                public int getCount() {
                    return sites.size();
                }
    
                @Override
                public View getView(int position, View convertView, ViewGroup parent) {
                    String name = getItem(position);
                    View view = convertView;
                    if (view == null) {
                        LayoutInflater vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                        view = vi.inflate(resourceId, null);
                    }
                    TextView mTextView = (TextView) view.findViewById(R.id.ridedetails);
                    mTextview.setText(name);
                    Button mButton = (Button) view.findViewById(R.id.button);
                    mButton.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            Toast.makeText(context, name, Toast.LENGTH_SHORT).show();
                        }
                    });
    
                    return view;
                }
            }
    

    set adapter in listview like below code.

    l1.setAdapter(new MyAdapter(getApplicationContext(), R.layout.home_resource, allNames));