I am new to Android.
I am trying to refer a View by Id from a separate class than MainActivity.
Note: My app has single activity.
Main Activity:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState)//Activity Oncreate callback
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) //Oncreate Options_menu callback
{
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
case R.id.option1:
//Here am calling a method from another class
SecondClass secondClassObject=new SecondClass();
secondClassObject.method1();
}
return true;
}
Second Class:
public class SecondClass {
public void method1(){
TextView tv1 = (TextView)findViewById(R.id.textView);
tv1.setText("");
}
}
How to refer to the textView by ID in the SecondClass? How to set the context as MainActivity in this SecondClass?
Add an Activity parameter for your method
public void method1(Activity act){
TextView tv1 = (TextView)act.findViewById(R.id.textView);
tv1.setText("");
}
From your activity define an Activity variable Activity act; so as to use it across other functions .Assign a value of your Activity to the variable act=this; and finaly use it on the function you want.
public class MainActivity extends AppCompatActivity {
Activity act;
#Override
protected void onCreate(Bundle savedInstanceState)//Activity Oncreate callback
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
act=this;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) //Oncreate Options_menu callback
{
act=this;
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
case R.id.option1:
//Here am calling a method from another class
//SecondClass secondClassObject=new SecondClass();
//secondClassObject.method1();
SecondClass secondClassObject=new SecondClass();
secondClassObject.method1(act);
}
return true;
}
you can also pass the parent layout view
public void method1(View act){
TextView tv1 = (TextView)act.findViewById(R.id.textView);
tv1.setText("");
}
And call it like so
SecondClass secondClassObject=new SecondClass();
secondClassObject.method1(findViewById(R.id.your_parent_layout));
Avoid using passing Activity method if its not absolutely necessary to avoid possibilities of memory leaks.
Related
I'm working on the android self study Sunshine app and I'm having trouble getting extra menu entries in the action bar.
The most likely reason I've found, is that the OnCreate method of my frame class is not being called and thus the menu is not being inflated.
Here's my MainActivity code:
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d("MainActivity","OnCreate Started 1");
if (savedInstanceState == null) {
Log.d("MainActivity","OnCreate Started 2");
ForecastFragment MyFragment = new ForecastFragment();
if (MyFragment == null){
Log.d("MainActivity","OnCreate Started 3");
}
else{
getSupportFragmentManager().beginTransaction()
.add(R.id.container, MyFragment)
.commit();}
}
}
Here is now the code of my ForecastFragment class:
public class ForecastFragment extends Fragment {
public ForecastFragment() {
}
//#Override
protected void OnCreate(Bundle savedInstanceState){
Log.d("Forecastfragment","OnCreate Started");
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// Inflate the menu; this adds items to the action bar if it is present.
inflater.inflate(R.menu.forecastfragment, menu);
}
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_refresh) {
FetchWeatherTask WeatherTask = new FetchWeatherTask();
WeatherTask.execute();
return true;
}
return super.onOptionsItemSelected(item);
}
When I run the app, I don't see the logging that the OnCreate method of the ForecastFragment class is being called.
Any ideas?
This is not the exact inherited onCreate method of Fragment
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i(TAG, "onCreate()");
}
it should be onCreate not OnCreate
When trying to make an android app, I encountered the error:
No enclosing instance of the type MainActivity is accessible in scope on the line
Toast.makeText(MainActivity.this, "Swag", Toast.LENGTH_SHORT).show();
This is my MainActivity.java:
public class MainActivity extends ActionBarActivity {
static Button btn;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment()).commit();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.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();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment implements View.OnClickListener {
public PlaceholderFragment() {
}
#Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "Swag", Toast.LENGTH_SHORT).show();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container,false);
btn=(Button) rootView.findViewById(R.id.test_button);
btn.setOnClickListener(this);
return rootView;
}
}
}
You must use getActivity() inside the fragment.
Be careful, if you are doing some background job, or any other async task when it return, getActivity() may be null. So every time you use it check for null.
Further information on fragments, you can use this.
I am currently building for a minimum SDK of 10, so I have to use the android-support-v7-appcompat library to implement ActionBar. I have setup the ActionBar, but I want to now add a ListActivity, however this requires extending my class and Java doesn't have multiple inheritance. What should I do?
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu items for use in the action bar
MenuInflater inflater = getMenuInflater();
getSupportActionBar().setIcon(R.drawable.ic_action_search);
getSupportActionBar().setDisplayShowHomeEnabled(false);
getSupportActionBar().setDisplayShowTitleEnabled(false);
inflater.inflate(R.menu.main_activity_actions, menu);
return super.onCreateOptionsMenu(menu);
}
}
ListActivity hasn't been ported to AppCompat. Probably because you should consider it 'deprecated', and instead use a ListFragment.
Fragments will work with a ActionBarActivity, just make sure they are fragments from the support library.
Have a read through this link about fragments.
For your use case, I would just define the fragment in xml.
The easiest way to do this is to use a ListFragment inside of the ActionBarActivity. I did it like this:
public class MyActivity extends ActionBarActivity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
MyFragment fragment = new MyFragment();
getSupportFragmentManager().beginTransaction().replace(android.R.id.content, fragment).commit();
}
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home: {
finish();
break;
}
default: {
break;
}
}
return true;
}
public static class MyFragment extends ListFragment {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
}
public void onListItemClick(ListView listView, View view, int position, long id) {
...
}
}
}
This way you don't even need an xml for it, and it works well.
I'm following a tutorial on ActionBarCompat that also enables a search text area. I extended the ActionBarActivity from the v7 support lib. When I try to override these two methods it can't find them in the superclass. I went to source and looked at the superclass' methods and I can't locate them there as well. The two methods are onQueryTextSubmit and onQueryTextChange
This was the tutorial.
Any idea what I am doing wrong?
This is the error when I hover over the methods:
The method onQueryTextChange(String) of type MainActivity must override or implement a supertype method
public class MainActivity extends ActionBarActivity{
private SearchView mSearchView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
ViewConfiguration config = ViewConfiguration.get(this);
Field menuKeyField = ViewConfiguration.class.getDeclaredField("sHasPermanentMenuKey");
if(menuKeyField != null) {
menuKeyField.setAccessible(true);
menuKeyField.setBoolean(config, false);
}
} catch (Exception ex) {
// Ignore
}
}
#Override
public boolean onQueryTextSubmit(String s) {
Toast.makeText(this, s, Toast.LENGTH_LONG).show();
return true;
}
#Override
public boolean onQueryTextChange(String s) {
return false;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
MenuItem searchItem=menu.findItem(R.id.action_search);
mSearchView = (SearchView) MenuItemCompat.getActionView(searchItem);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()){
case R.id.action_search:
mSearchView.setIconified(false);
return true;
}
return false;
}
It sounds like you are not implementing the class that is needed for those methods.
public class MainActivity extends ActionBarActivity implements SearchView.OnQueryTextListener
Make sure that you implemented SearchView.OnQueryTextListener.
I have a small question about the Data consistence in the onCreate() function. For better understanding my example:
public class Test extends Activity {
public String isThisConsistent1;
public int isThisConsistent2;
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.Test, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.Item_1:
getSomething();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.Test);
/*Very, very long taking code like a huge loop */
isThisConsistent1 = ...;
isThisConsistent2 = ...;
}
private void getSomething(){
String test1 = isThisConsistent1;
int test2 = isThisConsistent2;
}
}
So my question is: Is it possible to click the Item on my ActionBar before the onCreate() function is finished? Because then I would call the function getSomething() before the Data was set in the onCreate() function.
As you can see in the lifecycle documentation, the onCreate method is called before view is visible. This means, the answer is no, you can't click the button before the onCreate finishes.