Dujana Abrar
Dujana Abrar

Reputation: 111

My listview is showing null after applying onItemClickListener

I applied OnItemClickListener and now it is giving me NPE. Before applying the listener it was working fine

Here is my code

package com.example.pc.jbossoutreachapp;

import android.app.ProgressDialog;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.HashMap;

public class repositories extends AppCompatActivity {

    private String TAG = MainActivity.class.getSimpleName();

    private ProgressDialog ProgDialog;
    private ListView listview;

    private static String url = "https://api.github.com/orgs/JBossOutreach/repos";

    ArrayList<HashMap<String,String>> RepoDetails;


    public void link(View view)
    {
        TextView text = findViewById(R.id.Repolink);
        String url = text.getText().toString();

        Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
        startActivity(browserIntent);

    }



    public void Contributors(View view)
    {
        listview = this.findViewById(android.R.id.list);
        listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            public void onItemClick(AdapterView<?> parent, View view,
                                    int position, long id) {
                TextView textView = view.findViewById(R.id.RepositoryName);
                String text = textView.getText().toString();
                Log.e("nameeeeee", "Name is  == "+text);

            }});
        String url1 = "https://api.github.com/repos/JBossOutreach/lead-management-android/contributors";
        Intent intent = new Intent(this, contributors.class);
        Bundle bundle = new Bundle();
        bundle.putString("url", url1);
        intent.putExtras(bundle);
        startActivity(intent);
    }

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

        RepoDetails = new ArrayList<>();

        listview = (ListView)findViewById(R.id.list);

        new GetContacts().execute();
    }


    private class GetContacts extends AsyncTask<Void, Void, Void>
    {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();

            ProgDialog = new ProgressDialog(repositories.this);
            ProgDialog.setMessage("Please wait...");
            ProgDialog.setCancelable(false);
            ProgDialog.show();
        }

        @Override
        protected Void doInBackground(Void... voids) {

            HttpHandler sh = new HttpHandler();

            String Json_String = sh.makeServiceCall(url);

            Log.e(TAG, "Response from url: " + Json_String);

            if(Json_String != null)
            {
                try
                {
                  JSONArray array = new JSONArray(Json_String);
                    for(int i = 0; i < array.length(); i++)
                    {
                        JSONObject ob = array.getJSONObject(i);

                        String name = ob.getString("name");

                        JSONObject owner = ob.getJSONObject("owner");
                        String link = owner.getString("html_url");

                        HashMap<String, String> contact = new HashMap<>();

                        contact.put("name", name);
                        contact.put("link", link+"/"+name);

                        RepoDetails.add(contact);
                    }
                }
                catch(final JSONException e)
                {
                    Log.e(TAG, "Json parsing error: " + e.getMessage());
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(getApplicationContext(),
                                    "Json Parsing error: " + e.getMessage(), Toast.LENGTH_LONG).show();                        }
                    });
                }
            }

            else
            {
                Log.e(TAG, "Couldn't get Json from server");
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(getApplicationContext(),
                                "Couldn't get json from server ", Toast.LENGTH_LONG).show();
                    }
                });
            }

            return null;
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);
            if(ProgDialog.isShowing())
            {
                ProgDialog.dismiss();
            }

            ListAdapter adapter = new SimpleAdapter(
                    repositories.this, RepoDetails, R.layout.repo_list_item, new String[]
                    {"name", "link"}, new int[]{R.id.RepositoryName, R.id.Repolink});

            listview.setAdapter(adapter);
        }

    }

}

And i checked this answer too but this does not solved my problem

Android: listview crashes

I know i am doing something very wrong. Please help!!

Update

Logcat:

 Caused by: java.lang.reflect.InvocationTargetException
        at java.lang.reflect.Method.invoke(Native Method)
        at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:385)
        at android.view.View.performClick(View.java:5678) 
        at android.view.View$PerformClick.run(View.java:22667) 
        at android.os.Handler.handleCallback(Handler.java:836) 
        at android.os.Handler.dispatchMessage(Handler.java:103) 
        at android.os.Looper.loop(Looper.java:203) 
        at android.app.ActivityThread.main(ActivityThread.java:6293) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1065) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:926) 
     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ListView.setOnItemClickListener(android.widget.AdapterView$OnItemClickListener)' on a null object reference
        at com.example.pc.jbossoutreachapp.repositories.Contributors(repositories.java:51)
        at java.lang.reflect.Method.invoke(Native Method) 
        at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:385) 
        at android.view.View.performClick(View.java:5678) 
        at android.view.View$PerformClick.run(View.java:22667) 
        at android.os.Handler.handleCallback(Handler.java:836) 
        at android.os.Handler.dispatchMessage(Handler.java:103) 
        at android.os.Looper.loop(Looper.java:203) 
        at android.app.ActivityThread.main(ActivityThread.java:6293) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1065) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:926) 

Upvotes: 2

Views: 90

Answers (3)

ManishPrajapati
ManishPrajapati

Reputation: 514

You are initializing listview two times. Also in Contributors method you are using "android.R.id.list", you should use "R.id.list".

Try this, Remove the initialization from Contributors method, and add onItemClickListener in onCreate instead of contributors method.

Upvotes: 0

Doctiger
Doctiger

Reputation: 2508

From your code, the NPE is obviously related with that the listview is null. This means that your activity couldn't find the ListView with the id of android.R.id.list. You should double check your XML layout to be sure that there is a ListView with the id of android.R.id.list.

It should be something like the following. android:id="@android:id/list

EDIT:

Here is how to fix the issue of item click not working. In ListView, when there are clickable elements in item view, click event is not working for item view itself. To fix this, you just need to add two lines of code to make them not focusable. And here is full code for your reference.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:padding="5dp">

    <TextView
        android:id="@+id/RepositoryName"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:paddingTop="15dp"
        android:paddingBottom="8dp"
        android:textColor="@color/NameRepo" />

    <TextView
        android:id="@+id/Repolink"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:onClick="link"
        android:paddingBottom="8dp"
        android:textColor="@color/colorAccent" />

    <Button
        android:id="@+id/button2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:onClick="Contributors"
        android:text="@string/Contributors" />


</LinearLayout>

You just need to update your layout file - repo_list_item. As you can see, I just added following two lines to TextView with id Repolink and Button with id button2 and that's all.

android:focusable="false"
android:focusableInTouchMode="false"

PS: We should now use RecyclerView to implement a list in android app, not ListView anymore.

Upvotes: 0

Aaron
Aaron

Reputation: 3894

Just before setting setOnItemClickListener, I think make a typo in your id, you should probably need to replace your id android.R.id.list to R.id.list:

listview = this.findViewById(android.R.id.list);

Or simply just remove it as you have already assigned the ListView in onCreate.

Also it's safe to move this block of lines to onCreate instead, just in case if your method Contribute is being called prematurely:

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

    RepoDetails = new ArrayList<>();

    listview = this.findViewById(R.id.list);
    listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            TextView textView = view.findViewById(R.id.RepositoryName);
            String text = textView.getText().toString();
            Log.e("nameeeeee", "Name is  == "+text);
        }
    });
// ...

Upvotes: 1

Related Questions