0

I am getting my Json Object / Array from my Api and print it into my view, foreach array I print the id the name in my MainActivity.

Foreach array data I create a button. I want to move to another Activity and show the related data of the current array.

My view looks something like this:

________________________
id     name      button      <- if one clicks on the button another activity shall show the description of it
________________________

My big issue is how to show the related data in another activity.

My MainActivity looks like this:

public class MainActivity extends AppCompatActivity
        implements NavigationView.OnNavigationItemSelectedListener {


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

    private ProgressDialog pDialog;
    private ListView lv;

    // URL to get contacts JSON
    private static String url = "http://192.168.178.58:8888/test";

    ArrayList<HashMap<String, String>> contactList;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        contactList = new ArrayList<>();

        new GetContacts().execute();

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

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });

        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
                this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        drawer.setDrawerListener(toggle);
        toggle.syncState();

        NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
        navigationView.setNavigationItemSelectedListener(this);

    }

    /**
     * Async task class to get json by making HTTP call
     */
    private class GetContacts extends AsyncTask<Void, Void, Void> {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            // Showing progress dialog
            pDialog = new ProgressDialog(MainActivity.this);
            pDialog.setCancelable(false);
            pDialog.show();

        }

        @Override
        protected Void doInBackground(Void... arg0) {
            HttpHandler sh = new HttpHandler();

            // Making a request to url and getting response
            String jsonStr = sh.makeServiceCall(url);

            if (jsonStr != null) {
                try {
                    // Getting JSON Array node
                    JSONArray jsonArray = new JSONArray(jsonStr);

                    // looping through All Contacts
                    for (int i = 0; i < jsonArray.length(); i++) {
                        JSONObject c = jsonArray.getJSONObject(i);

                        String id = c.getString("id");
                        String name = c.getString("name");
                        String description = c.getString("description");

                        // tmp hash map for single contact
                        HashMap<String, String> data = new HashMap<>();

                        // adding each child node to HashMap key => value
                        data.put("id", id);
                        data.put("name", name);
                        data.put("description", description);

                        // adding contact to contact list
                        contactList.add(data);
                    }
                } 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. Check LogCat for possible errors!",
                                Toast.LENGTH_LONG)
                                .show();
                    }
                });

            }

            return null;
        }

        /**
         * In onPostExecute() method the progress dialog is dismissed and the array list data is displayed in list view using an adapter.
         * @param result
         */
        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);
            // Dismiss the progress dialog
            if (pDialog.isShowing())
                pDialog.dismiss();
            /**
             * Updating parsed JSON data into ListView
             */
            ListAdapter adapter = new SimpleAdapter(
                    MainActivity.this, contactList,
                    R.layout.list_item,
                    new String[]{"name", "description"},
                    new int[]{R.id.name, R.id.description});

            lv.setAdapter(adapter);
        }

    }

}

Edit:

this is how I made an intent:

public void openDetails() { // button onclick name
   Intent myIntent = new Intent(MainActivity.this, DetailActivity.class);
    myIntent.putExtra("key", value);
    MainActivity.this.startActivity(myIntent);
}
utdev
  • 3,942
  • 8
  • 40
  • 70

2 Answers2

1

In general you can use a singleton to share non primitive data between activities.

something like this,

public class MyData {
  private Object data;
  public Object getData() {
   return data;
  }
  public void setData(Object data) {
   this.data = data;
  }

  private static final MyData myData = new MyData();
  public static MyData getInstance() {
   return myData;
  }
}

then in the first activity:

MyData.getInstance().setData(objToShare);

and in the second:

objShared = MyData.getInstance().getData();
//do something
Karim
  • 8,454
  • 3
  • 25
  • 33
  • I do not quiet get how I should use this in my case – utdev Nov 28 '16 at 16:47
  • From what i have understood you want to share data between the main activity and a second one. when you receive the response from the api you can put the data retrieved in a singleton and follow the example i provided above. – Karim Nov 28 '16 at 16:51
  • 1
    In some cases I just use the `Application` class (assuming you override it) to store such things. – ygesher Nov 28 '16 at 16:57
  • Data doesn't need stored app-wide. The question was just how to get an adapter item displayed in another Activity – OneCricketeer Nov 28 '16 at 17:05
0

Your current implementation doesn't know which button was clicked. All buttons are going to have the same click event.

Solution - don't put buttons on your ListView. Just handle a click on the "row".

To start this off, you'll want to replace your list of HashMap<String, String> in favor of a custom POJO class.

See - Parcelable objects

public class Contact implements Parcelable {
    private String id, name, description;

    // TODO: Getters & setters
    // TODO: Actually implement Parcelable
}

Then, update your adapter. Instead of a SimpleAdapter.

See - Custom Adapter

private ContactAdapter adapter; // Top of class
...
// onCreate
    contactList = new ArrayList<Contact>();
    lv = (ListView) findViewById(R.id.list);
    adapter = new ContactAdapter(MainActivity.this, contactList);
    lv.setAdapter(adapter); // Set this here, not in the AsyncTask
...
// doInBackground
    contactList.add(someContact);
    // adapter.add(someContact); // Can also do this
// onPostExecute
    adapter.notifyDataSetChanged(); // Refresh the adapter, don't lv.setAdapter again. 

And your AsyncTask

    // tmp object for single contact
    Contact c = new Contact();

    // adding each child node to object
    c.setID(id);
    c.setName(name);
    c.setDescription(description);

    // adding contact to contact list
    contactList.add(c);

Gson would help with this if you didn't want to do it manually. Retrofit could replace your whole AsyncTask, but I'll leave that up to you to research.


Now, back to the "click event".
Since this Contact object is Parcelable, you pass it through an Intent just like anything else.

// onCreate
    lv = (ListView) findViewById(R.id.list);
    // This is a click per-row
    lv.setOnItemClickListener(new OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, final int position, long id) {    
            Contact clicked = adapter.getItem(position);
            displayContact(clicked);  
        }
    });

I like defining separate methods to make the code clearer.

private void displayContact(Contact c) {
    Intent intent = new Intent();
    intent.putExtra("contact", c);  // The piece you're looking for
    startActivity(intent);
}

To get it from intent in another activity:

Contact c = getIntent().getExtras().getParcelable("contact");

Refer - Android: How to pass Parcelable object to intent and use getParcelable method of bundle?

Community
  • 1
  • 1
OneCricketeer
  • 179,855
  • 19
  • 132
  • 245