1

I'm developing an app (a dictionary).
Getting Words, Pronunciation, Definition, Image name from a link in JSON format using Volley.
Then parsing JSON and showing a list of words and an EditText at the top of a screen in order to search words. Everything is OK. But I don't know how to handle click events, how to pass data of selected item to another activity and receive there.
So when a list item is selected DetailsActivity should display the Word , Pronunciation, Definition and set image name if there is.

the JSON which I'm receiving from web service

{
  "words": [

    {
      "id": "1",
      "the_word": "first word",
      "pronunciation": "pronun",
      "definition": "def",
      "image_name": "img_01"
    },
    {
      "id": "2",
      "the_word": "second word",
      "pronunciation": "pronun2",
      "definition": "def2",
      "image_name": "img_02"
    },
    {
      "id": "3",
      "the_word": "third word",
      "pronunciation": "pronun3",
      "definition": "def3",
      "image_name": "img_03"
    }

  ]
}

Word.java class as model

public class Word {

    private String the_word;
    private String pronunciation;
    private String definition;
    private String image_name;


    public String getThe_word() {
        return the_word;
    }

    public void setThe_word(String the_word) {
        this.the_word = the_word;
    }

    public String getPronunciation() {
        return pronunciation;
    }

    public void setPronunciation(String pronunciation) {
        this.pronunciation = pronunciation;
    }

    public String getDefinition() {
        return definition;
    }

    public void setDefinition(String definition) {
        this.definition = definition;
    }

    public String getImage_name() {
        return image_name;
    }

    public void setImage_name(String image_name) {
        this.image_name = image_name;
    }


}

WordAdapter.java class as adapter ( I'll take care of image later)

public class WordAdapter extends BaseAdapter {

    Context context;
    LayoutInflater inflater;
    List<Word> data;

    public WordAdapter(Context context, List<Word> data) {
        this.context = context;
        this.data = data;
    }




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

    @Override
    public Object getItem(int position) {
        return null;
    }

    @Override
    public long getItemId(int position) {
        return 0;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {

        TextView word;

        inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        View itemView = inflater.inflate(R.layout.word_item, parent, false);

        word = (TextView) itemView.findViewById(R.id.t_word);
        word.setText(data.get(position).getThe_word());

        return itemView;
    }

}

And here is the list activity class

public class WordsList extends AppCompatActivity {


        private static final String url = "http://mywebaddress.com/dictionary/showWords.php";

        ListView listView;
        WordAdapter adapter;
        ProgressDialog PD;
        List<Word> arrayListOfWords;
        EditText editText;


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

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

            editText = (EditText) findViewById(R.id.search);

            PD = new ProgressDialog(this);
            PD.setMessage("Loading ...");
            PD.show();

            getListView().setOnItemClickListener(new ListItemClickListener());

            ReadDataFromDB();

            editText.addTextChangedListener(filterTextWatcher);

        }



        private void ReadDataFromDB() {
            PD.show();

            JsonObjectRequest jsonObject = new JsonObjectRequest(Method.POST, url,new Response.Listener<JSONObject>() {

                        @Override
                        public void onResponse(JSONObject response) {

                                arrayListOfWords = new ArrayList<>();

                                try {
                                    JSONArray ja = response.getJSONArray("words");
                                    for (int i = 0; i < ja.length(); i++) {
                                        JSONObject jsonWordsList = ja.getJSONObject(i);
                                        Word word = new Word();
                                        word.setThe_word(jsonWordsList.optString("the_word"));
                                        word.setPronunciation(jsonWordsList.optString("pronunciation"));
                                        word.setDefinition(jsonWordsList.optString("definition"));
                                        word.setImage_name(jsonWordsList.optString("image_name"));

                                        arrayListOfWords.add(word);

                                        PD.dismiss();

                                    }
                                } catch (JSONException e) {
                                    e.printStackTrace();
                                    Toast.makeText(getApplicationContext(), "inside JSONException", Toast.LENGTH_LONG).show();
                                }

                            adapter = new WordAdapter(WordsList.this, arrayListOfWords);
                            editText.addTextChangedListener(filterTextWatcher);
                            listView.setAdapter(adapter);

                            adapter.notifyDataSetChanged();
                        }
                    }, new Response.ErrorListener() {

                @Override
                public void onErrorResponse(VolleyError error) {
                    PD.dismiss();
                }
            });


            AppController.getInstance().addToRequestQueue(jsonObject);

        }

        private TextWatcher filterTextWatcher = new TextWatcher() {

            public void afterTextChanged(Editable s) {
            }

            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }

            public void onTextChanged(CharSequence s, int start, int before, int count) {
                List<Word> foundItems = new ArrayList<>();
                if (arrayListOfWords != null) {
                    getWordsList(s, foundItems);
                    listView.setAdapter(new WordAdapter(getApplicationContext(), foundItems));
                    adapter.notifyDataSetChanged();
                }

            }

        };

        public void getWordsList(CharSequence s, List<Word> list) {
            for (Word word : arrayListOfWords) {
                if (word.getThe_word().contains(s)) {
                    list.add(word);
                }
            }
        }

        public ListView getListView() {
            return listView;
        }



        class ListItemClickListener implements ListView.OnItemClickListener {

            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

                Intent i = new Intent(WordsList.this,DetailsActivity.class);
                i.putExtra("selected_word", (Parcelable) arrayListOfWords.get(position));
                startActivity(i);

            }

        }
    }

As I said everything is OK But on list item click !
actually this piece of code is the problem:

class ListItemClickListener implements ListView.OnItemClickListener {

        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

            Intent i = new Intent(WordsList.this,DetailsActivity.class);
            i.putExtra("selected_word", (Parcelable) arrayListOfWords.get(position));
            startActivity(i);

        }

    }

How can I pass the_word, pronunciation, definition and image_name of selected item of the list to the DetailsActivity.java and how to get them there?

Thank You!


Edit
So I find a very easy way to pass data which I always use !!!
BUT I'm not sure if it's the best practice And I'm sure there is a better way. Thinking about the time there is much more data you are going to pass, and then my solution would be frustrating.
Here is what I'm doing :
Using putExtra to send ...

class ListItemClickListener implements ListView.OnItemClickListener {

        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

            String passingWord = String.valueOf(arrayListOfWords.get(position).getThe_word());
            String passingPr = String.valueOf(arrayListOfWords.get(position).getPronunciation());
            String passingDf = String.valueOf(arrayListOfWords.get(position).getDefinition());
            String passingIm = String.valueOf(arrayListOfWords.get(position).getImage_name());

            Intent i = new Intent(WordsList.this,DetailsActivity.class);
            i.putExtra("selected_word", passingWord);
            i.putExtra("selected_pr", passingPr);
            i.putExtra("selected_df", passingDf);
            i.putExtra("selected_im", passingIm);
            startActivity(i);

        }

    }

And in DetailsActivity.java getting StringExtra :

Intent intent = getIntent();
String the_word = intent.getStringExtra("selected_word");
String pronunciation = intent.getStringExtra("selected_pr");
String definition = intent.getStringExtra("selected_df");
String image_name = intent.getStringExtra("selected_im");


Edit
The above code is OK until you search a word and than click on a list item, DetailsActivity show something different of selected word details .
Actually when you search for a word, there might be two or three items shown on the list by filter letters. if you choose the first one , in DetailsActivity you will see the details of the first word from the whole dictionary list. It means the selected position is wrong .
So I changed my code and rewrite it again and this time it's working as I expected. I will share it as the answer to this question for whom might be in such trouble .

unknown
  • 29
  • 1
  • 7
  • 1
    Possible duplicate of [How do I pass data between activities on Android?](http://stackoverflow.com/questions/2091465/how-do-i-pass-data-between-activities-on-android) – OneCricketeer Mar 24 '16 at 15:25
  • 2
    You should make the entire Word object Parcelable. Please also see [How can I make my objects Parcelable?](http://stackoverflow.com/questions/7181526/how-can-i-make-my-custom-objects-be-parcelable) – OneCricketeer Mar 24 '16 at 15:26

2 Answers2

0

I think the best way to achieve sending composite objects between activities is the EventBus. You can simply create a new object you want to pass (it can be of any type, e.g. custom class of yours) and use:

MyClass myObject = new MyClass; // initialize the object how you like
//and post it
eventBus.post(myObject);

Then in the 'receiver' activity, make a @Subscribe method which will listen for this type of Object being received:

@Subscribe
public void onMyClassEvent(MyClass myObject){
    //your logic here
}

It should not be hard getting the EventBus to work, they have great guides, but if you are having any trouble, write.

Vucko
  • 7,371
  • 2
  • 27
  • 45
  • no problem, mate. Use EventBus once, and you'll love it. You'll see my point. The best thing about it is that you can achieve all kinds of things with it, primary one being transferring whole different objects between activities, fragments, services etc.. – Vucko Mar 26 '16 at 09:38
0

try below code for get intent data:

String the_word = getIntent().getExtras().getString("selected_word");
String pronunciation = getIntent().getExtras().getString("selected_pr");
String definition = getIntent().getExtras().getString("selected_df");
String image_name = getIntent().getExtras().getString("selected_im");
Ravi Vaghela
  • 3,420
  • 2
  • 23
  • 51