eoin.mn
eoin.mn

Reputation: 3

How to open a new activity and scroll to specific child view?

Dear StackOverflow community, could I ask for some help?

I’m a very amateur coder, trying to develop an app version of a reference document, and it needs to be searchable. I can’t get the search results to link back to the document activity and scroll down to the target text.

I’ve got a MainActivity displaying the document in a scrollview within a co-ordinator layout, so I can use the floating action button. At the top of the content_main layout I created buttons that will scroll down to specific child views (section headings) of the scrollview using smoothScrollTo. They work fine.

But the document needs to be searchable. I created an ArrayList that gives search results in a listview (from an example in www.androidhive.com), in an activity named SearchActivity. I’m trying to work out how to use clicks on listview search results to open the content_main layout and scroll down to a specific child view. I’ve tried the approaches suggested in SO (Click on a TextView opens new activity and jumps to a specific id ; Android New Intent start particular method ) and neither have worked. I can’t find anything else online that gives me any idea how to manage it. Can anyone suggest a way? Here is one way I tried. This opens the activity, but doesn’t scroll.

I'd be grateful for any help.

MainActivity:

public class MainActivity extends AppCompatActivity { 


Button buttonHeader3a, buttonHeader3b, buttonHeader3c, buttonHeader3d; 
ScrollView myView; 

TextView myTV; 
TextView hdr3a, hdr3b, hdr3c, hdr3d; 

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

    FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); 
    fab.setOnClickListener(new View.OnClickListener() { 

@Override 
       public void onClick(View v) { 
       Intent i = new Intent(MainActivity.this, SearchActivity.class); 
       startActivity(i); 
        } 
    }); 


    buttonHeader3a = (Button) findViewById(R.id.b1); 
    buttonHeader3b = (Button) findViewById(R.id.b2); 
    buttonHeader3c = (Button) findViewById(R.id.b3); 
    buttonHeader3d = (Button) findViewById(R.id.b4); 

    myView = (ScrollView) findViewById(R.id.myview); 
    myTV = (TextView) findViewById(R.id.ch3p16); 

    hdr3a = (TextView) findViewById(R.id.header3a);   //hdr = header 
    hdr3b = (TextView) findViewById(R.id.header3b); 
    hdr3c = (TextView) findViewById(R.id.header3c); 
    hdr3d = (TextView) findViewById(R.id.header3d); 


    buttonHeader3a.setOnClickListener(new Button.OnClickListener() { 


        public final void onClick(View view) { 
            new Handler().post(new Runnable() { 
                @Override 
                public void run() { 
                    myView.smoothScrollTo(0, hdr3a.getTop()); 
                } 
            }); 
        } 
    }); 

    buttonHeader3b.setOnClickListener(new Button.OnClickListener() {   

        public final void onClick(View view) { 
            new Handler().post(new Runnable() { 
                @Override 
                public void run() { 
                    myView.smoothScrollTo(0, hdr3b.getTop()); 
                } 
            }); 
        }
    }); 

    buttonHeader3c.setOnClickListener(new Button.OnClickListener() { 

        public final void onClick(View view) { 
            new Handler().post(new Runnable() { 
                @Override 
                public void run() { 
                    myView.smoothScrollTo(0, hdr3c.getTop()); 
                } 
            }); 
        } 
    }); 


    buttonHeader3d.setOnClickListener(new Button.OnClickListener() { 


        public final void onClick(View view) { 
            new Handler().post(new Runnable() { 
                @Override 
                public void run() { 
                    myView.smoothScrollTo(0, hdr3d.getTop()); 
                } 
            }); 
        } 
    }); 
} 

    public void onButtonLinkPrealerting (View v) { 
        if (v.getId() == R.id.buttonLinkPrealerting) { 
            Intent i = new Intent(MainActivity.this, Chapter4.class); 
            startActivity(i); 
        } 
    } 

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    // Inflate the menu; this adds items to the action bar if it is present. 
    getMenuInflater().inflate(R.menu.menu_main, menu); 
    return true; 
} 

@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    // Handle action bar item clicks here. The action bar will 
    // automatically handle clicks on the Home/Up button, so long 
    // as you specify a parent activity in AndroidManifest.xml. 
    int id = item.getItemId(); 

    //noinspection SimplifiableIfStatement 
    if (id == R.id.action_settings) { 
        return true; 
    } 

    return super.onOptionsItemSelected(item); 
} 


// Here's where i'm trying to pick up an intent in SearchActivity and scroll down 


@Override 
protected void onNewIntent (Intent intent) { 
    super.onNewIntent (intent); 
    if(intent.getStringExtra("methodName").equals("myMethod")) { 
        myView.post(new Runnable() { 
            @Override 
            public void run() { 
                myView.smoothScrollTo(0, hdr3a.getTop()); 
            } 
        }); 
    } 
} 

// similar methods to scroll to other sections... 

}

SearchActivity:

public class SearchActivity extends Activity {


// List view
private ListView lv;

// Listview Adapter
ArrayAdapter<String> adapter;

// Search EditText
EditText inputSearch;


// ArrayList for Listview
ArrayList<HashMap<String, String>> productList;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_search);


    // Listview Data
    String products[] = {
            "first very long string",
            "second very long string",
    // Several other very long strings
            };

    lv = (ListView) findViewById(R.id.list_view);
    inputSearch = (EditText) findViewById(R.id.inputSearch);

    // Adding items to listview
    adapter = new ArrayAdapter<String>(this, R.layout.list_item, R.id.product_name, products);
    lv.setAdapter(adapter);

    /**
     * Enabling Search Filter
     * */
    inputSearch.addTextChangedListener(new TextWatcher() {

        @Override
        public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
            // When user changed the Text
            SearchActivity.this.adapter.getFilter().filter(cs);
        }

        @Override
        public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
                                      int arg3) {
            // TODO Auto-generated method stub

        }

        @Override
        public void afterTextChanged(Editable arg0) {
            // TODO Auto-generated method stub
        }
    });


    lv.setOnItemClickListener(
       new AdapterView.OnItemClickListener() {
     @Override
     public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
     String a = parent.getAdapter().getItem(position).toString();


     if (a.equals"first very long string"))
      {
      Intent intent = new Intent ();
      intent.setClass (getBaseContext(), MainActivity.class);
      intent.putExtra("methodName", "myMethod");
      startActivity(intent);
                                 }

      else

      if (a.equals"second very long string"))

 // more of the same

          }
          });
          }
          }


Upvotes: 0

Views: 2015

Answers (1)

NSimon
NSimon

Reputation: 5287

If I were you, I would move the logic of your onNewIntent (in MainActivity) into the onCreate instead.

According to the documentation,

Handle onNewIntent() to inform the fragment manager that the state is not saved. If you are handling new intents and may be making changes to the fragment state, you want to be sure to call through to the super-class here first. Otherwise, if your state is saved but the activity is not stopped, you could get an onNewIntent() call which happens before onResume() and trying to perform fragment operations at that point will throw IllegalStateException because the fragment manager thinks the state is still saved.

Therefore, simply check whether you have data passed to your activity onCreate when creating it :

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    //All your other initialisations

    //Get any potential intent that was passed to the activity
    Intent intent = getIntent();
    if (intent != null) {
      //Is there a string extra in that intent?
      String extra = intent.getStringExtra("methodName");
      //Is that string not empty and equals what you're looking for?
      if (!TextUtils.isEmpty(extra) && extra.equals("myMethod")) {
        myView.post(new Runnable() { 
          @Override 
          public void run() { 
              myView.smoothScrollTo(0, hdr3a.getTop()); 
          } 
        }); 
      }
  }
} 

Upvotes: 2

Related Questions