简体   繁体   中英

OnClick not being detected in RecyclerView for Intent

I have an issue with my onClick method for one of my RecyclerView's for an app I am working on. Strangely, the exact same logic works with other recyclerviews in my app, the difference this time however is that I am parsing JSON data (which is where I think I am missing something). The onClick is not being detected at all in the simulator or on my phone, nothing is even being logged in log cat (I am using Android Studio 1.3.1), so I am completely baffled! I believe I have all the appropriate permissions and intent filters defined in my Android Manifest file (which you will find below).

This is the recycler View that i want to trigger the intent from (intent = new Intent(context, AdminTeam.class); this OnClick is NOT BEING DETECTED - It just displays the recycler view with the items and then lets me click on each row but nothing happens! :

RecyclerViewAdapterNationalCommiitee.java

public class RecyclerViewAdapterNationalCommiitee extends RecyclerView.Adapter<RecyclerViewAdapterNationalCommiitee.MyViewHolder> {

    private Context context;
    private LayoutInflater inflater;

    //private RecyclerViewAdapterAdminTeam ra;

    //Variable for the on click Listener
    private ClickListener clickListener;

    List<SubInformation> data = Collections.emptyList();

    //Passing in the array list argument
    public RecyclerViewAdapterNationalCommiitee(Context context, List<SubInformation> data) {

        this.context = context;
        inflater = LayoutInflater.from(context);

        //Setting the array list data to the argument passed in
        this.data = data;
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        //Inflating the row and getting the root of view of the custom row natcom (Linear Layout)
        View view = inflater.inflate(R.layout.custom_row_natcom, parent, false);

        //Passing the root view through as an argument
        MyViewHolder holder = new MyViewHolder(view);

        //Returning the view holder
        return holder;
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {

        //This will get the current position of the Information object from the Information array
        SubInformation current = data.get(position);

        holder.title.setText(current.getTitle());
    }

    //Setting up a click listener which lets me set up an object that implements the interface
    public void setClickListener(ClickListener clickListener) {

        //Initialising the clickListener
        this.clickListener = clickListener;
    }

    @Override
    public int getItemCount() {
        return data.size();
    }

    class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

        TextView title;

        public MyViewHolder(View itemView) {
            super(itemView);

            //Here setting the id of the textview in the recycler view holder to be the list view from the custom_row xml
            title = (TextView) itemView.
                    findViewById(R.id.listText);
        }

        @Override
        public void onClick(View v) {

            Intent intent = null;

            switch (getAdapterPosition()) {
                case 0:
                    //Toast.makeText(v.getContext(), "Default Case", Toast.LENGTH_SHORT).show();
                    //break;
                    intent = new Intent(context, AdminTeam.class);
                    //intent.putExtra("JSON Admin", ra.getItemCount());
                    break;

                case 1:
                    Toast.makeText(v.getContext(), "Default Case", Toast.LENGTH_SHORT).show();
                    break;
                default:
                    break;
            }

            //In order for an activity to begin, a context needs to be passed in
            //context.startActivity(new Intent(context, Introduction.class));
            context.startActivity(intent);
            //If the method is not called (Error handling to avoid NULL POINTER EXCEPTION ERROR)
            if (clickListener != null) {
                //Trigger the appropriate call. getPosition will get the latest position of the item clicked by the user
                clickListener.itemClicked(v, getAdapterPosition());
            }

        }

    }

    //Here, inside the adapter have made an interface. This interface is implemented in the Tab1 class Fragment.
    public interface ClickListener {
        void itemClicked(View view, int position);
    }
}

NationalCommittee.java

public class NationalCommittee extends BaseActivity implements RecyclerViewAdapterNationalCommiitee.ClickListener {

    private RecyclerView mRecyclerView;

    //Creating an instance of the adapter object
    private RecyclerViewAdapterNationalCommiitee adapter;

    private static final int ITEM_COUNT = 2;

    @Override
    //public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    protected void onCreate(Bundle savedInstanceState){

        super.onCreate(savedInstanceState);
        setContentView(R.layout.national_committee);

        //final View layout = inflater.inflate(R.layout.national_committee, container, false);

        //Calling Activate Toolbar method (with the Back button enabled)
        activateToolbarWithHomeEnabled();

        //Instantiating the recycler view as defined in national_committee
        mRecyclerView=(RecyclerView) findViewById(R.id.natcom_recycler_view);

        //Adding item decoration. Recycler view divider
        mRecyclerView.addItemDecoration(new DividerItemDecoration(this,DividerItemDecoration.VERTICAL_LIST));

        //Initialising the adapter - Passing in the activity and the getData method
        adapter=new RecyclerViewAdapterNationalCommiitee(this,getData());

        //Here passing in the click listener into the Adapter. 'this' signifies that it is the fragment that handles the click listener.
        //This is possible as the on Click Listener interface is being implemented.
        adapter.setClickListener(this);

        //Setting the adapter
        mRecyclerView.setAdapter(adapter);

        //Setting the Layout
        //mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));

        mRecyclerView.setItemAnimator(new DefaultItemAnimator());

    //return layout;

}


    //Creating an array list of information objects that can be passed into the recycler view
    public static List<SubInformation> getData() {

        List<SubInformation> data = new ArrayList<>();

        //String array of text for the recycler view
        String[] text = {"Admin Team", "Team Coordinators"};
        //String[] subText = {"What is NHSF?", "Admin Team and Team Coordinators"};

        //For loop to go through entire length of the menu string
        //for(int i=0; i<menu.length; i++) {

        for(int i=0; i<ITEM_COUNT; i++){


            //Information current = new Information();
            //Information subCurrent = new Information();

            //current.title = text[i];
            //subCurrent.subtitle = subText[i];

            data.add(new SubInformation(text[i]));

        }

        return data;
    }

    @Override
    public void itemClicked(View view, int position) {

    }
}

Here is the RecyclerView that I want to trigger the intent from:

RecyclerViewAdapterAdminTeam.java

public class RecyclerViewAdapterAdminTeam extends RecyclerView.Adapter<RecyclerViewAdapterAdminTeam.MyViewHolder> {

    private LayoutInflater inflater;

    private AdminTeam activity;

    //Variable for the on click Listener
    //private ClickListener clickListener;

    private List<JSONAdminItem> data = Collections.emptyList();

    private Context mContext;


    //Passing in the array list argument
    public RecyclerViewAdapterAdminTeam(AdminTeam activity, Context context, List<JSONAdminItem> data){

        this.mContext = context;
        this.activity = activity;

        inflater = LayoutInflater.from(context);

        //Setting the array list data to the argument passed in
        this.data = data;
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        //Inflating the row and getting the root of view of the custom row natcom (Linear Layout)
        View view = inflater.inflate(R.layout.custom_row, parent, false);

        //Passing the root view through as an argument
        MyViewHolder holder = new MyViewHolder(view);

        //Returning the view holder
        return holder;
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {

        //This will get the current position of the JSONAdminItem object from the array
        JSONAdminItem adminItem = data.get(position);

        //Setting the title to be the Admin Role (converting from JSON)
        holder.title.setText(Html.fromHtml(adminItem.getAdminRole()));
        //Setting the subtitle to be the Name (converting from JSON)
        holder.subTitle.setText(Html.fromHtml(adminItem.getName()));
    }

    /*
    //Setting up a click listener which lets me set up an object that implements the interface
    public void setClickListener(ClickListener clickListener){

        //Initialising the clickListener
        this.clickListener=clickListener;
    }
    */

    @Override
    public int getItemCount() {
        return data.size();

        //return (null != data ? data.size() : 0);
    }

    public interface ClickListener {
    }

    class MyViewHolder extends RecyclerView.ViewHolder {

        TextView title;
        TextView subTitle;

        public MyViewHolder(View itemView) {
            super(itemView);

            //Here setting the id of the textview in the recycler view holder to be the list view from the custom_row xml
            title = (TextView) itemView.
                    findViewById(R.id.listText);
            subTitle = (TextView) itemView.findViewById(R.id.subTitle);
        }

        /*
        @Override
        public void onClick(View v) {

        }
        */
    }

    /*
    //Here, inside the adapter have made an interface. This interface is implemented in the Tab1 class Fragment.
    public interface ClickListener {
        void itemClicked(View view, int position);
    }
    */


}

In this class I am doing my JSON Parsing and this is the class that I wish to intent to from the onClick in the RecyclerViewNationalCommittee.java file:

AdminTeam.java

public class AdminTeam extends BaseActivity implements RecyclerViewAdapterAdminTeam.ClickListener{

    private RecyclerView mRecyclerView;

    //Creating an instance of the adapter object
    private RecyclerViewAdapterAdminTeam adapter;

    private List<JSONAdminItem> AdminTeamList;

    private AdminTeam activity;

    //private static final int ITEM_COUNT = 5;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.admin_team);

        //Calling Activate Toolbar method (with the Back button enabled)
        activateToolbarWithHomeEnabled();

        //Instantiating the recycler view as defined in admin_team
        mRecyclerView = (RecyclerView) findViewById(R.id.adminteam_recycler_view);

        //Adding item decoration. Recycler view divider
        mRecyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST));

        //Initialising the adapter - Passing in the activity and the parsed Admin Team List
        adapter = new RecyclerViewAdapterAdminTeam(activity, this, AdminTeamList);

        //Setting the adapter
        mRecyclerView.setAdapter(adapter);

        //Setting the Layout
        //mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));

        mRecyclerView.setItemAnimator(new DefaultItemAnimator());

        //Downloading data from below url (Universal Resource Locator) to obtain data from the Admin database
        final String url = "http://dbchudasama.webfactional.com/jsonscriptAdmin.php";
        new AsyncHTTPTask().execute(url);
    }

    public class AsyncHTTPTask extends AsyncTask<String, Void, Integer> {

        @Override
        protected Integer doInBackground(String... params) {
            Integer result = 0;
            HttpURLConnection urlConnection;
            try {
                URL url = new URL(params[0]);
                urlConnection = (HttpURLConnection) url.openConnection();
                int statusCode = urlConnection.getResponseCode();

                // 200 represents HTTP OK
                if (statusCode == 200) {
                    BufferedReader r = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
                    StringBuilder response = new StringBuilder();
                    String line;
                    while ((line = r.readLine()) != null) {
                        response.append(line);
                    }
                    parseResult(response.toString());
                    result = 1; // Successful
                } else {
                    result = 0; //"Failed to fetch data!";
                }
            } catch (Exception e) {
                Log.d("Exception Caught", e.getLocalizedMessage());
            }
            return result; //"Failed to fetch data!";
        }

        @Override
        protected void onPostExecute(Integer result) {

            super.onPostExecute(result);

            //adapter.getItemCount();

            if (result == 1) {
                //Intent intent = getIntent();
                //intent.getSerializableExtra("JSON Admin");
                //Initialising the adapter - Passing in the activity and the parsed Admin Team List
                adapter = new RecyclerViewAdapterAdminTeam(activity, AdminTeam.this, AdminTeamList);
                //Setting the adapter
                mRecyclerView.setAdapter(adapter);
            } else {
                Toast.makeText(AdminTeam.this, "Failed to fetch data!", Toast.LENGTH_SHORT).show();
            }
        }

    }

    //This method will parse the RAW data downloaded from the server
    private void parseResult(String result) {
        try {
            //Converting into a JSON Object
            JSONObject response = new JSONObject(result);
            //Now converting this JSON Object into and a JSON Array
            JSONArray AdminArrays = response.getJSONArray("Admin Arrays");
            AdminTeamList = new ArrayList<>();

            //String[] AdminRole = {};

            for (int i = 0; i < AdminArrays.length(); i++) {
                JSONObject AdminArrayObject = AdminArrays.getJSONObject(i);
                JSONAdminItem item = new JSONAdminItem();
                item.setAdminRole(AdminArrayObject.getString("AdminRole"));
                item.setName(AdminArrayObject.getString("Name"));

                this.AdminTeamList.add(item);

                Log.e("Admin Role", AdminArrayObject.getString("AdminRole"));
                Log.e("Name", AdminArrayObject.getString("Name"));
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }
}

Here is my JSONAdminItem Class file:

JSONAdminItem.java

public class JSONAdminItem {
    private String AdminRole;
    private String Name;

    public String getAdminRole(){
        return AdminRole;
    }

    public void setAdminRole(String AdminRole) {
        this.AdminRole = AdminRole;
    }

    public String getName(){
        return Name;
    }

    public void setName(String Name) {
        this.Name = Name;
    }
}

Here is my AndroidManifest.xml file in which I have added the relevant permissions and have also added the activity as seen:

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.divyeshbc.NHSF" >

    <!-- Parse settings -->
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />

    <permission
        android:name="com.divyeshbc.NHSF.permission.C2D_MESSAGE"
        android:protectionLevel="signature" />

    <uses-permission android:name="com.divyeshbc.NHSF.permission.C2D_MESSAGE" />

    <!--  -->
    <application
        android:name=".ParseApplication"
        android:allowBackup="true"
        android:icon="@mipmap/nhsf_app_logo_androidx144"
        android:label="@string/app_name"
        android:theme="@style/Theme.Custom" >
        <activity
            android:name=".SplashActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name">
            <!--android:parentActivityName=".SplashActivity">
            <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value="com.divyeshbc.NHSF.SplashActivity" />
            -->
            <intent-filter>
                <action android:name="android.intent.action.MAINACTIVITY" />

                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        <activity
            android:name=".tabs.aboutUs.Introduction"
            android:label="@string/Introduction"
            android:parentActivityName=".MainActivity" >
            <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value="com.divyeshbc.NHSF.MainActivity" />

            <intent-filter>
                <action android:name="android.intent.action.ACTION_VIEW" />

                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        <activity
            android:name=".tabs.aboutUs.NationalCommittee"
            android:label="@string/title_activity_natcom"
            android:parentActivityName=".MainActivity" >
            <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value="com.divyeshbc.NHSF.MainActivity" />
        </activity>
        <activity
            android:name=".tabs.aboutUs.AdminTeam"
            android:label="@string/title_activity_adminteam"
            android:parentActivityName=".tabs.aboutUs.NationalCommittee" >
            <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value="com.divyeshbc.NHSF.tabs.aboutUs.NationalCommittee" />
        </activity>

        <!-- Configuring Parse -->
        <service android:name="com.parse.PushService" />

        <receiver android:name="com.parse.ParseBroadcastReceiver" >
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
                <action android:name="android.intent.action.USER_PRESENT" />
            </intent-filter>
        </receiver>
        <receiver
            android:name="com.parse.ParsePushBroadcastReceiver"
            android:exported="false" >
            <intent-filter>
                <action android:name="com.parse.push.intent.RECEIVE" />
                <action android:name="com.parse.push.intent.DELETE" />
                <action android:name="com.parse.push.intent.OPEN" />
            </intent-filter>
        </receiver>
        <receiver
            android:name="com.parse.GcmBroadcastReceiver"
            android:permission="com.google.android.c2dm.permission.SEND" >
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
                <action android:name="com.google.android.c2dm.intent.REGISTRATION" />

                <category android:name="com.divyeshbc.NHSF" />
            </intent-filter>
        </receiver>
        <!--  -->
        <meta-data
            android:name="com.divyeshbc.NHSF.notifcation_icon"
            android:resource="@mipmap/nhsf_logo_push_android" />

    </application>

</manifest>

I can't understand why the onClick in RecylerViewAdapterNationalCommiitee.java is not being detected.

It's strange because this intent works:

            <activity
                android:name=".tabs.aboutUs.NationalCommittee"
                android:label="@string/title_activity_natcom"
                android:parentActivityName=".MainActivity" >
                <meta-data
                    android:name="android.support.PARENT_ACTIVITY"
                    android:value="com.divyeshbc.NHSF.MainActivity" />
            </activity>

whereas this doesn't:

             <activity
                android:name=".tabs.aboutUs.AdminTeam"
                android:label="@string/title_activity_adminteam"
                android:parentActivityName=".tabs.aboutUs.NationalCommittee" >
                <meta-data
                    android:name="android.support.PARENT_ACTIVITY"
                     android:value="com.divyeshbc.NHSF.tabs.aboutUs.NationalCommittee" />
            </activity>

Any guidance would be highly appreciated.

Thanks!

You never set any click listener on list items. Setting click listeners on each list item in onBindViewHolder will resolve the issue :

holder.itemView.setOnClickListener(...

Here is an alternative approach you can try. You can add clicklistener to the rootView in onBindViewHolder . Here is modified the adapter code which should work:

@Override
public void onBindViewHolder(MyViewHolder holder, int position) {

    //This will get the current position of the Information object from the Information array
    SubInformation current = data.get(position);

    holder.title.setText(current.getTitle());

    //add the click listener
    holder.root.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = null;

            switch (getAdapterPosition()) {
                case 0:
                    //Toast.makeText(v.getContext(), "Default Case", Toast.LENGTH_SHORT).show();
                    //break;
                    intent = new Intent(context, AdminTeam.class);
                    //intent.putExtra("JSON Admin", ra.getItemCount());
                    break;

                case 1:
                    Toast.makeText(v.getContext(), "Default Case", Toast.LENGTH_SHORT).show();
                    break;
                default:
                    break;
            }

            //In order for an activity to begin, a context needs to be passed in
            //context.startActivity(new Intent(context, Introduction.class));
            context.startActivity(intent);
            //If the method is not called (Error handling to avoid NULL POINTER EXCEPTION ERROR)
            if (clickListener != null) {
                //Trigger the appropriate call. getPosition will get the latest position of the item clicked by the user
                clickListener.itemClicked(v, getAdapterPosition());
            }

        }
    });
}

class MyViewHolder extends RecyclerView.ViewHolder{

    TextView title;
    View root; //save the root view and add the click listener on it in OnBindViewHolder

    public MyViewHolder(View itemView) {
        super(itemView);
        root = itemView;

        //Here setting the id of the textview in the recycler view holder to be the list view from the custom_row xml
        title = (TextView) itemView.
                findViewById(R.id.listText);
    }


}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM