0

I have an activity that loads text views into it. I add a click listener to these text views and want them to open up an activity with different values based on what I click. It ends up that no matter which I click, the same results show up, and more precisely, I use the same info in creating it - which I don't want to do.

public void setTextToTextView (JSONArray jsonArray)
{
    RelativeLayout layout = (RelativeLayout) findViewById(R.id.activity_main);
    String s = "";
    for (int i = 0; i < jsonArray.length(); i++) {
        TextView info = new TextView(this); //actually really confused as to what the context I'm setting is - why this? Just saw other people do it like so

        JSONObject json = null;
        try {
            json = jsonArray.getJSONObject(i);
            s = s + "ID : " + json.getString("Id") + " Parent: " + json.getString("Parent") +
                    " Content: " + json.getString("Content") + " User: " + json.getString("User") +
                    " Timestamp: " + json.getString("Timestamp") + "\n\n";
        } catch (JSONException e) {
            e.printStackTrace();
        }
        info.setText(s);
        try {
            info.setId(Integer.parseInt(json.getString("Id")));
        } catch (JSONException e) {
            e.printStackTrace();
        }
        info.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent myIntent = new Intent(MainActivity.this,
                        NewActivity.class);
                myIntent.putExtra("key", v.getId()); //this is always the same
                startActivity(myIntent);
            }
        });
        layout.addView(info);
    }
}

Using two text views, this results in the ID of the second view to always be the value of the key,value pair in the activity I start. I'm not sure what I'm doing wrong at the moment. I believe my problem is in this section, as I can't see where else it might come from.

Any help or suggestions on my code in general would be welcomed. Thank you.

This still isn't solved, so I'll focus on the problem area:

info.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Intent myIntent = new Intent(MainActivity.this,
                NewActivity.class);
        myIntent.putExtra("key", v.getId()); //this is always the same
        startActivity(myIntent);
    }
});

No matter what changes I make, this will always give me the exact same v.getId/v.getTag - every time.

Boken
  • 4,825
  • 10
  • 32
  • 42
bhow
  • 98
  • 9
  • What is the issue? It is not clear from your description. Are you not getting the extras in the new activity? Can you pls post the complete code? – siva Mar 05 '17 at 02:05
  • I have a for loop that should create multiple views, each with their own event listener. In my thinking, it seems these listeners should be creating separate activities (and pass separate values). Currently, if I have the for loop go through 2 jsonObjects, I will get the same v.getId() no matter which I click on. I want them to be different. – bhow Mar 05 '17 at 02:09
  • Are you sure your json has different Id for different objects ? please add log statement Log.d for jsonobjects and v.getId() in onClick and share output from logcat – Shailendra Singh Rajawat Mar 05 '17 at 02:10
  • They do have different Ids. I only have two json objects that I'm going through - id of 1 and id of 3. If I change the for loop to i < 1, I will get id of 1. If I have i < 2, both text views are printed, but when I click either I get id of 3. – bhow Mar 05 '17 at 02:12
  • Create an array of textviews and keep that out of your for loop. Array length should be equal to your json array length. – siva Mar 05 '17 at 02:25
  • I'm fairly certain the problem is - when - the OnClickListener sets the key,value. It doesn't occur until I actually click the view (onClick event, duh). Is this not the correct way to implement it? My intent is for it to be buttons, with pre supplied information, that, when clicked, open up an activity with correct extras. Finding the extras onClick seems to be messing things up – bhow Mar 05 '17 at 02:27
  • @7383 Sorry, I'm actually very new to Java and Android Studio. What would be the purpose of creating an array of textviews? And where would I put the text views into the array at (where I have addView(info)?) and then how would I put them all into my layout? – bhow Mar 05 '17 at 02:29
  • First create array of textviews like this and keep this line out of for loop. Textview [] info= new Textview [jsonArray.length]. Then inside the loop don't create textview. Instead of info use info[i] – siva Mar 05 '17 at 02:42
  • I'm not sure I understand the purpose of that. Don't I still need new TextView(this); ? And what is making an array doing differently than just having individual TextViews that go out of scope? – bhow Mar 05 '17 at 02:47
  • In your approach I guess the textviews are getting overwritten with the latest values hence you are getting the last value in the view. So better to move therm out of your for loop. You better try the approach what I have mentioned – siva Mar 05 '17 at 06:47
  • I did try that, but it didn't work without adding: new TextView(this); After adding that, the results were still the same. – bhow Mar 05 '17 at 06:49
  • Well, there are actually different problems now, but it gives me more to think on, anyway. – bhow Mar 05 '17 at 07:39

2 Answers2

1

As a first step, I would move the OnclickListener to outsdie the loop, as it always does the same thing:

View.OnClickListener view_ocl = new View.OnClickListener() {
    @Override
    public void onClick(View v)
    {
        Intent myIntent = new Intent(MainActivity.this, NewActivity.class);
        myIntent.putExtra("key", v.getId()); //this is always the same
        startActivity(myIntent);
    }};

for(int i =0; i <jsonArray.length(); i++)
{
    // ... as before
    info.setOnClickListener(view_ocl);
    layout.addView(info);
}

As you do, you need to explicitly set the Id, or in some way put an identifier in the view so that your onClick code (which is the same for each View), knows which View has been clicked. At the moment you are reliant on whatever arbitrary Id the system gives to the view.

Neil Townsend
  • 6,024
  • 5
  • 35
  • 52
  • You say explicitly set the Id - but isn't that what I'm doing? Above the OnClickListener I call the setId method and set each view's Id manually. – bhow Mar 05 '17 at 08:26
  • 1
    So, in the second view created you have text which has the information from the first two, and that text has ID's listed of 1 and 3 for the two returned objects, but whichever View you click on the id is 3? – Neil Townsend Mar 05 '17 at 08:43
  • The current effect of my app is that it prints out the Json object as text. Currently I print out 3 json objects as strings. Their IDs are 1 2 and 3 and this prints out correctly before checking view IDs. After clicking any of them, I have a print statement inside of the onClick method which prints out 3 no matter which view I click on. It of course also takes me to an activity where the text being displayed is the same, as though I had clicked the same button. – bhow Mar 05 '17 at 08:47
  • 1
    Thanks - still thinking. Out of interest, why don't you just have one OnClickListener for all of the Views given that they all execute the saem sequence: get click, find id, start activity telling it that id ...? – Neil Townsend Mar 05 '17 at 08:49
  • I've never coded in Java before/haven't done any app work and this has all been incredibly confusing. So far this (kind of) makes sense and doing it any other way leaves me unsure of what I'm doing. This is before click and after click: http://imgur.com/a/RXkUv The right side is, of course, if I click any of the 3. – bhow Mar 05 '17 at 08:52
  • I've put how to do that in the answer and corrected my misunderstanding in the answer, but I don't know if that will solve it. – Neil Townsend Mar 05 '17 at 09:01
  • My results seem to be unchanged. I'm not sure how TextViews are treated as buttons - is there anyway text that should belong to one view is being covered by that of another view? – bhow Mar 05 '17 at 09:10
  • From the point of view of the system, all widgets (buttons, text views etc) are descendants of a core 'view' class. That class has certain core attributes which all things then have (layout functionality, clickability ...) – Neil Townsend Mar 05 '17 at 09:12
  • Sorry, I'm obviously missing something, the code looks good. BTW, a good explanation of using ids is at http://stackoverflow.com/questions/8460680/how-can-i-assign-an-id-to-a-view-programmatically – Neil Townsend Mar 05 '17 at 09:17
1

I create a new project with your code but the result is correct just as what you hope.Are you sure that your third TextView does not cover the previous ones?

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

    int [] a = {1,2};        
    String [] s = {"textView1","textView2"};
    for(int i =0; i <a.length; i++)
    {
        TextView info = new TextView(this); //actually really confused as to what the context I'm setting is - why this? Just saw other people do it like so
        info.setText(s[i]);
        info.setId(a[i]);
        info.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                Toast.makeText(getApplicationContext(),
                       "clicked:"+v.getId(),Toast.LENGTH_SHORT).show();
                Intent myIntent = new Intent(MainActivity.this,
                        NewActivity.class);
                myIntent.putExtra("key", v.getId()); //this is always the same
                startActivity(myIntent);
            }
        });
        layout.addView(info);
    }

The gif:

https://i.stack.imgur.com/gvV27.gif

Sardar Usama
  • 19,536
  • 9
  • 36
  • 58
xiang si
  • 26
  • 3
  • That's what I began to suspect. The text does not overlap but is there a chance the area I'm clicking is covered by only one text view? I also tried adding a separate text view with random characters and it is put into the middle of the other text, overlapping. I'm not sure why the original posts would be put below each other and then another view be put on top. – bhow Mar 05 '17 at 18:41
  • Try to use `LinearLayout` instead of `RelativeLayout` and check that if the – xiang si Mar 05 '17 at 19:23
  • This seems to have been the problem. For some reason, though, I was creating 1, 1 2, 1 2 3 - so when I clicked 1 2 or 3, the 3rd view had all 3 elements and would think I clicked 3. Now just to figure out why It's duplicating text. And I got it - String S is declared outside the for loop so it maintains the Json object information from previous loops - that's why it overlapped with identical information with a relative layout. – bhow Mar 05 '17 at 19:42