0

Is it possible to return peepWithPics after sending it to my XMLPullParserHandler so I can call it onCreate and set it to a listView adapter. I am not sure how to pass it to any other method or class for us. Calling the listViewAdapter works in this method but I am unable to get setOnItemClickLIstener to work so thinking if I can create the adapter in the onCreate and then setOnItemCLickLister, should help me with me move forward with my development.

Also with OkHttp3 I read that doing the call with enqueue was doing so asynchronously yet I get an error.

android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. This error is at the code line

listView.setAdapter(adapter);

The whole method is as

public void getXMLData() {
        OkHttpClient client = getUnsafeOkHttpClient();
        Request request = new Request.Builder()
                .url(myURL)
                .build();
        client.newCall(request).enqueue(new Callback() {
            //    android.os.Handler mainHanlder = new android.os.Handler(context.getMainLooper());

            @Override
            public void onFailure(Call call, IOException e) {
                e.printStackTrace();
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                final String responseData = response.body().string();
                final InputStream stream = new ByteArrayInputStream(responseData.getBytes());

                /*mainHanlder.post(new Runnable() {

                    @Override
                    public void run() {*/
                ArrayList<PeepWithPic> peepWithPics;
                XMLPullParserHandler parserHandler = new XMLPullParserHandler();
                peepWithPics = (ArrayList<PeepWithPic>) parserHandler.parse(stream);
                        /*ListViewAdapter adapter = new ListViewAdapter(getApplicationContext(), peepWithPics);
                        listView.setAdapter(adapter);
                        listView.setVisibility(View.VISIBLE);
                        mProgressBar.setVisibility(View.GONE);*/
                    /*}
                });*/
            }
        });
    }

I have tried adding after mProgressBar is set to gone.

listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                                    @Override
                                    public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                                        Toast.makeText(getApplicationContext(), "WORKS FROM RUNONUI", Toast.LENGTH_LONG).show();
                                    }

I have also tried the same setOnItemClickListener in the onCreate method

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        context = getApplicationContext();
        listView = (ListView) findViewById(R.id.contactListView);
        mProgressBar = (ProgressBar) findViewById(R.id.progressBar);
        mProgressBar.setVisibility(View.VISIBLE);
        getXMLData();
    }

The getXMLData method is called in the onCreate

Adam Gardner
  • 1,216
  • 1
  • 9
  • 21
  • 1
    Possible duplicate of [Okhttp response callbacks on the main thread](http://stackoverflow.com/questions/24246783/okhttp-response-callbacks-on-the-main-thread) – kandroidj Jan 10 '17 at 16:27
  • When I try any of those suggestions from that post, setOnItemClickListeners do not work when called from new Runnable, runOnUI or onCreate. I am still not seeing how to pass peepWihtPics to onCreate so I can try and set listView and adapter there and not on that runnable in the onResponse – Adam Gardner Jan 10 '17 at 16:47
  • can you update your question with what you have tried, also where is your call to getXMLData() ? – kandroidj Jan 10 '17 at 16:56
  • I have updated the question with more code and the getXMLData is called onCreate from same class. – Adam Gardner Jan 10 '17 at 17:03

1 Answers1

1

The solution should be as simple as using the Activity's runOnUiThread(Runnable) Method, also i would create the Adapter and set it before the call to getXMLData():

Add these as member variables of your Activity

List<PeepWithPic> mPeepWithPics = new ArrayList<PeepWithPic>(); 
ListViewAdapter mAdapter;

Then initialize your Adapter in onCreate():

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        context = getApplicationContext();
        listView = (ListView) findViewById(R.id.contactListView);
        mProgressBar = (ProgressBar) findViewById(R.id.progressBar);
        mProgressBar.setVisibility(View.VISIBLE);
        mAdapter = new ListViewAdapter(this, mPeepWithPics);
        listView.setAdapter(mAdapter);
        /* THIS DOES NOT WORK WHEN YOU HAVE A CLICKABLE VIEW IN A CUSTOM ADAPTER
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener(){
             @Override
             public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                 Toast.makeText(getApplicationContext(), "WORKS FROM RUNONUI", Toast.LENGTH_LONG).show();
             }
        }); */
        getXMLData();
    }

Then change your method to:

public void getXMLData() {
    OkHttpClient client = getUnsafeOkHttpClient();
    Request request = new Request.Builder()
            .url(myURL)
            .build();
    client.newCall(request).enqueue(new Callback() {

        @Override
        public void onFailure(Call call, IOException e) {
            e.printStackTrace();
        }

        @Override
        public void onResponse(Call call, Response response) throws IOException {
            final String responseData = response.body().string();
            final InputStream stream = new ByteArrayInputStream(responseData.getBytes());
            XMLPullParserHandler parserHandler = new XMLPullParserHandler();
            final ArrayList<PeepWithPic> peepWithPics = (ArrayList<PeepWithPic>) parserHandler.parse(stream);
            mPeepWithPics.clear();
            mPeepWithPics.addAll(peepWithPics);

            /* Now tell the adapter on the UI thread its data changed*/
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                   mAdapter.notifyDataSetChanged();
                   listView.setVisibility(View.VISIBLE);
                   mProgressBar.setVisibility(View.GONE);
                }
            });
        }
    });
}

UPDATE

For handling the click, you have to add an OnItemClickListener in your Adpater on the root layout since, your Adapter is custom and the View contains a clickable Widget.

Good luck and happy coding!

kandroidj
  • 13,784
  • 5
  • 64
  • 76
  • I updated my code as above but I am running into this error on mAdapter = new,.... I get Error:(57, 49) error: incompatible types: List cannot be converted to ArrayList – Adam Gardner Jan 10 '17 at 18:03
  • So the code runs again but I am still running into the issue of not being able to call setOnItemClickListener. I have tried to call it on the runOnUiThread and after the adapter is set onCreate. I am just trying to show a Toast to make sure its working and nothing. – Adam Gardner Jan 10 '17 at 18:35
  • see update above, you should be adding your listener in onCreate – kandroidj Jan 10 '17 at 18:41
  • That is what I am doing, but the actual Toast is never displayed when clicking any position within the listView – Adam Gardner Jan 10 '17 at 18:45
  • post your XML above then, probably something there blocking the ListView from receiving clicks – kandroidj Jan 10 '17 at 18:47
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/132841/discussion-between-inner-class7-and-adam-gardner). – kandroidj Jan 10 '17 at 18:50