How from class BasicActivity call method stackAFragment from subclass Sub?
I want to have an opportunity to replace Fragment in my Activity Sub from any Activity that extends BasicActivity by using menu. I am going to create a method in Sub for each item menu. Here is a simple example how I see it:
public class BasicActivity extends FragmentActivity {
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.m_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case R.id.stad:
TabHost tabHost = (TabHost) getParent().findViewById(android.R.id.tabhost);
tabHost.setCurrentTab(4); //here is me Sub.class
//How to call method stackAFragment here?
break;
default:
return false;
}
return true;
}
}
Subclass:
public class Sub extends BasicActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sub);
}
public void stackAFragment() {
Fragment f = new StadFr();
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.the_frag, f);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.addToBackStack(null);
ft.commit();
}
}
Create an overridable method in BasicActivity (with an empty implementation for instance) and override it in Sub.
public class BasicActivity extends FragmentActivity {
protected void onTabChanged(){ }
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case R.id.stad:
TabHost tabHost = (TabHost) getParent().findViewById(android.R.id.tabhost);
tabHost.setCurrentTab(4); //here is me Sub.class
onTabChanged();
break;
default:
return false;
}
return true;
}
public class Sub extends BasicActivity {
protected void onTabChanged() { stackAFragment(); }
....
}
You can make your BasicActivity class implement method stackAFragment() and override it in your subclass. You can also declare the method abstract in your BasicActivity which will then become also an abstract class.
super.stackAFragment(). But this method must be defined in your BasicActivity. It may be abstract if you want.
This should provide you with the wanted functionality:
Activity activity = getLocalActivityManager().getActivity( tabHost().getCurrentTabTag() );
if( activity instanceof Sub )
((Sub) activity).stackAFragment();
Related
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.
I have to set the listener for a NavigationView in my main class. But the main, will containt a lot of stuff, and I want to have it the most "separated" possible.
So I will do listeners in their own java files, to something like:
navigationView.setNavigationItemSelectedListener(new NavigationListener());
The problem comes, that I have to call getSupportFragmentManager , but is not accesible, so, I suppose that I need to do something like: context.getSupportFragmentManager to make ir "work".
But I don't know how to get the context.
How can I get it?
ListenerClass:
public class NavigationListener implements NavigationView.OnNavigationItemSelectedListener {
#Override
public boolean onNavigationItemSelected(MenuItem item) {
boolean fragmentTransaction = false;
String TAG = "NavigationViewListener";
Logger.init(TAG);
Fragment fragment = null;
switch (item.getItemId()){
case R.id.nav_home:
fragment = new FragmentHome();
fragmentTransaction = true;
break;
case R.id.nav_map:
fragment = new FragmentMap();
fragmentTransaction = true;
break;
case R.id.nav_log_out:
Logger.d("Pulsada opnciĆ³n de LogOut");
break;
}
if(fragmentTransaction){
getSupportFragmentManager().beginTransaction()
.replace(R.id.main_content, fragment)
.commit();
item.setChecked(true);
getSupportActionBar().setTitle(item.getTitle());
}
}
}
You could just pass the instance of your FragmentActivity to NavigationListener as a constructor param:
public class NavigationListener implements NavigationView.OnNavigationItemSelectedListener {
FragmentActivity activity;
public NavigationListener(FragmentActivity activity) {
this.activity = activity;
}
#Override
public boolean onNavigationItemSelected(MenuItem item) {
// ...
if(fragmentTransaction){
activity.getSupportFragmentManager().beginTransaction()
.replace(R.id.main_content, fragment)
.commit();
// ...
}
}
}
From your FragmentActivity:
navigationView.setNavigationItemSelectedListener(new NavigationListener(this));
I have an activity with fragment pager and I want to know how to call an asynctask located on that activity from fragment .
AddActivity.java
public class AddActivity extends FragmentActivity {
ViewPager vp;
ProgressDialog dialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add);
vp = (ViewPager) findViewById(R.id.pager);
PagerAdapter pa = new FragPagerAdapter(getSupportFragmentManager());
vp.setAdapter(pa);
}
//This void to get All field from the differents fragments and put them into jsonObject
protected JSONObject createJsonObjectVR () {
...
}
// Call the Post Method
public class addVR extends AsyncTask<String, String, String> {
...
}
OtherFragment.java
public class OtherFragment extends Fragment {
Button btn;
public OtherFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_other, container, false);
btn = (Button) view.findViewById(R.id.send);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// Here I want to call the createVR asynctask in the parent Activity
}
});
return view;
}
}
FragPagerAdapter
public class FragPagerAdapter extends FragmentPagerAdapter {
public FragPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int index) {
switch (index) {
case 0:
// First Fragment The main
return new FirstFragment();
case 1:
// Milk (Second) fragment activity
return new SecondFragment();
case 2:
// Housing (Third) fragment activity
return new HousingFragment();
case 3:
//Feeding (fourth) fragment activity
return new FeedingFragment();
case 4:
// Other (Fith the last) fragment activity
return new OtherFragment();
}
return null;
}
#Override
public int getCount() {
// get item count - equal to number of tabs
return 5;
}
}
in your fragment :
((AddActivity) getActivity()).someMethodToCallAsyncTaskInAddActivity();
inf your AddActivity:
public void someMethodToCallAsyncTaskInAddActivity() {
new AsyncTask(someOptions_if_needed).execute();
}
One more option
public static class ASyncronius extends AsyncTask<Void, Void, Void>
if you make it static you can call this async task from anywhere
AddActivity.ASyncronius abs = new AddActivity.ASyncronius ();
abs.execute()
Edit 2014-11-11
if you use fragment in diffrent activitys, then you shuld make shure, that those activitys extends same master class, that contains async method.
class ParentActivity extends Activity {
someMethodToCallAsyncTaskInParentActivity(){
***new async execute***
}
public class async extends AsyncTask<void, void, void>{
***Some stuff***
}
}
Then:
class FirstActivity extends ParentActivity{
}
also
class SecondActivity extends ParentActivity{
}
in your fragment
((ParentActivity)getActivity()).someMethodToCallAsyncTaskInParentActivity();
or if you dont need in that other activity use async task, then just do some thing like this:
try{
((FirstActivity)getActivity()).someMethodToCallAsyncTaskInParentActivity();
} catch( Exception e) {
// this is not needed activity
}
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.