Change getSupportActionBar().setTitle value from another class - android

I have a class that gets actionbarsherlock oncreate and sets default values. How can I change this values from another class ?
sample codes that doesnt work :
public class MyActivity extends SlidingFragmentActivity {
public static String abs;
#Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
abs = "text";
getSupportActionBar().setTitle(abs);
}
}
External class:
MyActivity.abs = "new value";

It is definitely not the recommended way to set the title, however, it should work if you remove the assignment abs = "text"; ...
public class MyActivity extends SlidingFragmentActivity {
public static String abs;
#Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getSupportActionBar().setTitle(abs);
}
}
... and call MyActivity.abs = "new value";some where before the activity is created the first time.
Anyhow I'd propose to pass the title as an extra into the activity ...
Intent intent = new Intent(context, MyActivity.class);
intent.putExtra("title", "Another Headline");
context.startActivity(intent);
... and evaluate that one from the intent:
public class MyActivity extends SlidingFragmentActivity {
#Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Bundle extras = getIntent().getExtras();
String title = "Default Headline";
if (extras != null && extras.containsKey("title")) {
title = intent.getStringExtra("title");
}
getSupportActionBar().setTitle(title);
}
}
p.s. setting title after creation:
If you can reference the activity directly, for instance because you are in a fragment, you might add a method like ...
public class MyActivity extends SlidingFragmentActivity {
public void setTitle(String title) {
this.getSupportActionBar().setTitle(title);
}
....
}
... and call it accordingly:
getActivity().setTitle("Another Headline");
The most sophisticated way to pass any kind of arguments to existing activities allowing them to process them in any way would be using a BroadcastReceiver:
public abstract class MyActivity extends SlidingFragmentActivity {
public static final String SET_TITLE_ACTION = "com.myapp.SET_TITLE_ACTION";
public static final IntentFilter INTENT_FILTER = createIntentFilter();
private SetTitleReceiver setTitleReceiver = new SetTitleReceiver();
private static IntentFilter createIntentFilter() {
IntentFilter filter = new IntentFilter();
filter.addAction(SET_TITLE_ACTION);
return filter;
}
protected void registerSetTitleReceiver() {
registerReceiver(setTitleReceiver, INTENT_FILTER);
}
protected void unRegisterSetTitleReceiver() {
unregisterReceiver(setTitleReceiver);
}
public class SetTitleReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(SET_TITLE_ACTION)) {
Bundle extras = intent.getExtras();
if (extras != null && extras.containsKey("title")) {
title = intent.getStringExtra("title");
this.getSupportActionBar().setTitle(title);
}
}
}
}
}
Any Activity class that should be able to receive a title change has to register the BroadcasdtReceiver in onResume() and unregister it in onPause(). This way you can set the title of these activity instance by sending a broadcast event from anywhere:
Intent intent = new Intent(MyActivity.SET_TITLE_ACTION);
intent.putExtra("title", "Another Headline");
context.sendBroadcast(intent);
Hope this helps ... Cheers!

It doesn't work because your just changing the reference abs is pointing to.
If you want to change the title pass the SherlockActivity as a parameter to your method.
Example:
public class MyActivity extends SherlockActivity {
#Override
protected void onCreate(final Bundle savedInstanceState) {
new ChangeTitle(this).setTitle("test title");
}
}
class ChangeTitle {
String title;
SherlockActivity activity;
public ChangeTitle(SherlockActivity activity) {
this.activity = activity;
}
public void setTitle(String title) {
this.title = title;
activity.getSupportActionBar().setTitle(this.title);
}
}

Related

Can setContentView be replaced by android-annotations when espresso is used?

I have espresso test which verifies that text is displayed:
public class InformationActivityTests {
#Rule
public ActivityTestRule<InformationActivity_> mInformationActivityTestRule =
new ActivityTestRule<InformationActivity_>(InformationActivity_.class) {
#Override
protected Intent getActivityIntent() {
Intent i = new Intent(getTargetContext(), InformationActivity_.class);
i.putExtra("INFORMATION", "Espresso");
return i;
}
};
#Test
public void textIsDisplayed() {
onView(withText("Espresso")).check(matches(isDisplayed()));
}
}
This test passes when Activity has following code:
#EActivity
public class InformationActivity extends AppCompatActivity {
#ViewById(R.id.information_view)
TextView informationView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_information);
Intent intent = getIntent();
String information = intent.getStringExtra("INFORMATION");
informationView.setText(information);
}
}
but fails when I "move" setContentView to #EActivity annotation:
#EActivity(R.layout.activity_information)
public class InformationActivity extends AppCompatActivity {
#ViewById(R.id.information_view)
TextView informationView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
String information = intent.getStringExtra("INFORMATION");
informationView.setText(information);
}
}
Error is:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.edu/com.edu.InformationActivity_}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
Am I doing something wrong or is it an issue with espresso / android-annotations?
I've checked code generated by android-annotations when using #EActivity(R.layout.activity_information) and this is how onCreate looks like in generated class (InformationActivity_):
public void onCreate(Bundle savedInstanceState) {
OnViewChangedNotifier previousNotifier = OnViewChangedNotifier.replaceNotifier(onViewChangedNotifier_);
init_(savedInstanceState);
super.onCreate(savedInstanceState);
OnViewChangedNotifier.replaceNotifier(previousNotifier);
setContentView(R.layout.activity_information);
}
the problem is that it first calls super.onCreate (so onCreate from InformationActivity) where I handle intent and TextView and then it calls setContentView and this can't work like that.
The solution for this is what Be_Negative suggested, so using #AfterViews annotation. It also simplifies code a bit (I could remove onCreate method):
#EActivity(R.layout.activity_information)
public class InformationActivity extends AppCompatActivity {
#ViewById(R.id.information_view)
TextView informationView;
#AfterViews
void handleIntent() {
Intent intent = getIntent();
String information = intent.getStringExtra("INFORMATION");
informationView.setText(information);
}
}
Your problem is that you are never initializing informationview
public class InformationActivity extends AppCompatActivity {
#ViewById(R.id.information_view)
TextView informationView; //<-- Null
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
String information = intent.getStringExtra("INFORMATION");
informationView.setText(information); //<--STILL NULL
}
}
So you first will have to initialize that view.

passing data from (grand) parent to parent to child to (grand) child and back up to (Grand) parent activity in android

I have a grand parent activity called Department
public class Department extends AppCompatActivity {
RecyclerView recyclerView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_department);
.........
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Context context = v.getContext();
Intent intent = new Intent(context, DeptDetail.class);
Bundle extra = new Bundle();
extra.putString("Department", getAdapterPosition()+"");
intent.putExtras(extra);
context.startActivity(intent);
}
});
}
}
Sends data about Department position to DepartmentDeatail activity
public class DeptDetail extends AppCompatActivity implements View.OnClickListener{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dept_detail);
Bundle extra = getIntent().getExtras();
deptpos = Integer.parseInt(extra.getString("Department"));
.........
public void onClick(View v) {
int id= v.getId();
Intent in;
Bundle extras = new Bundle();
in = new Intent(DeptDetail.this, Mission.class);
extras.putString("Mission",mission[deptpos]);
extras.putString("Deptid", deptpos+"");
in.putExtras(extras);
startActivityForResult(in,1);
}
}
and DeptDetail activity sends same Deptpos to its child activity Mission
public class Mission extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mission);
Bundle extra = getIntent().getExtras();
String mission = extra.getString("Mission");
deptid=Integer.parseInt(extra.getString("Deptid"));
TextView txtmission = (TextView)findViewById(R.id.txtmission);
try {
txtmission.setText(mission);
}
catch (NullPointerException e)
{
txtmission.setText("");
}
}
}
And now I want same Deptid to be accessed in DeptDetail activity which always calls for intent from Department activity, which is not available as usual..
So please show me the way to pass the data to child and back to parent.
I tried
onActivityResult(..)
but it wasn't called before onCreate where extra is read and generating NullPointerException

pass string from fragment main activity to fragments activity in viewpager

i wanna pass a string to all fragment(child) from fragment activity (main), may be this picture can explain what exactly what i want to do
https://dl.dropboxusercontent.com/u/57465028/SC20140205-163325.png
so, from above picture...i wanna pass a string from edittext by press a button to all activity in viewpager....how could i do that?
i tried to follow this code https://stackoverflow.com/a/12739968/2003393 but it can't solved my problem..
please help me...i'm stuck
thank in advance.
here is my code from fragment activity (MainActivity)
public class Swipe_Menu extends FragmentActivity {
//String KeyWord;
//private static final String KEYWORD = "keyword";
private ViewPager _mViewPager;
private ViewPagerAdapter _adapter;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.swipe_menu_image);
Button Back = (Button)findViewById(R.id.account);
ImageButton Search = (ImageButton)findViewById(R.id.search);
EditText Keyword = (EditText)findViewById(R.id.keyword);
final String KeyWord = Keyword.getText().toString();
/**
* Back button click event
* */
Back.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
finish();
}
});
setUpView();
setTab();
}
protected void sendValueToFragments(String value) {
// it has to be the same name as in the fragment
Intent intent = new Intent("my_package.action.UI_UPDATE");
intent.putExtra("UI_KEY", KeyWord );
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
and here is my fragment (Child Activity)
public class Store_Swipe extends Fragment {
public static final String ACTION_INTENT = "my_package.action.UI_UPDATE";
String KeyWord;
private TextView kata_keyword;
protected BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if(ACTION_INTENT.equals(intent.getAction())) {
String value = intent.getStringExtra("UI_KEY");
updateUIOnReceiverValue(value);
}
}
};
private void updateUIOnReceiverValue(String value) {
// you probably want this:
KeyWord = value;
}
public static Fragment newInstance(Context context) {
Store_Swipe f = new Store_Swipe();
return f;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
IntentFilter filter = new IntentFilter(ACTION_INTENT);
LocalBroadcastManager.getInstance(getActivity()).registerReceiver(receiver, filter);
}
#Override
public void onDestroy() {
LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(receiver);
super.onDestroy();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
/*Bundle bundle = this.getArguments();
KeyWord = bundle.getString("keyword");*/
View view = inflater.inflate(R.layout.store_swipe, container, false);
init(view);
return view;
}
void init(View view) {
kata_keyword = (TextView) view.findViewById(R.id.keyword);
//ImageView image = (ImageView) view.findViewById(R.id.image_error);
kata_keyword.setText(KeyWord);
}
}
You don't have access directly to your fragments that reside in ViewPager so you can't reference them directly.
What I am doing in these cases is send a broadcast message from Activity to Fragments. For this reason register a BroadcatReceiver in the fragment (either in onCreate or onCreateView - your decision)m, set a custom action for that receiver (ex. "my_package.actions.internal.BROADCAST_ACTION"), don't forget to unregister the receiver from complementary method.
When you want to send a message from activity, create an intent with above mentioned action, add the string in intent extra and send the broadcast.
In your receiver's onReceive method (within the fragment), get the String from intent paramter and there you have the string.
Makes sense?
EDIT: To provide some code, below are the changes that I would make for fragment:
public class Store_Swipe extends Fragment {
public static final String ACTION_INTENT = "my_package.action.UI_UPDATE";
protected BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if(ACTION_INTENT.equals(intent.getAction())) {
String value = intent.getStringExtra("UI_KEY");
updateUIOnReceiverValue(value);
}
}
};
private void updateUIOnReceiverValue(String value) {
// you probably want this:
kata_keyword.setText(value);
}
String KeyWord;
private TextView kata_keyword;
public static Fragment newInstance(Context context) {
Store_Swipe f = new Store_Swipe();
return f;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
IntentFilter filter = new IntentFilter(ACTION_INTENT);
LocalBroadcastManager.getInstance(getActivity()).registerReceiver(receiver, filter);
}
#Override
public void onDestroy() {
LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(receiver);
super.onDestroy();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Bundle bundle = this.getArguments();
KeyWord = bundle.getString("keyword");
View view = inflater.inflate(R.layout.store_swipe, container, false);
init(view);
return view;
}
void init(View view) {
kata_keyword = (TextView) view.findViewById(R.id.keyword);
ImageView image = (ImageView) view.findViewById(R.id.image_error);
kata_keyword.setText(KeyWord);
}
}
And this code I would have from activity, the parameter is the value from EditText:
protected void sendValueToFragments(String value) {
// it has to be the same name as in the fragment
Intent intent = new Intent("my_package.action.UI_UPDATE");
intent.putExtra("UI_KEY", value);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
You would call this from the click listener that you would set in onCreate:
findViewById(R.id.button_id).setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
String valueThatYouWantToSend = null; /// just the value
sendValueToFragments(valueThatYouWantToSend);
}
});
// I think this solution will solved your issue
// In Main activity put your code -----------------------------------
public void onPageSelected(int position)
{
System.out.println("nilesh");
PageOneFragment f = new PageOneFragment();
f.getText();
PageTwoFragment ff = new PageTwoFragment();
ff.setText();
}
//in General Class ------------------------------------------------
public class General
{
public static String name="";
}
// first Fragment ---------------------------------------------
public void getText()
{
General.name = edittext.getText().toString();
}
// second Fragment ----------------------------------------------
public void setText()
{
System.out.println("name**" + General.name);
tv.setText(General.name);
}

How to return values from a java class that extends another class into an Activity

Let's say that I've the following main activity:
public class MwConsoleActivity extends Activity {
private classChild child = null;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
child = new classChild();
}
}
Then consider the implementation of the class "classChild":
public class MwBondingAgent extends SapereAgent {
MwBondingAgent(){}
public void AddEventListener(childAddedEvent event) {
//Send the data of event back to the main activity
}
}
I've tried to use IntentServices but was not able to receive the values back to the main activity. What would be the approach I've to take?
Cheers
Ali
You can use and intentFilter to listen for broadcasts.
Add this to the activity:
IntentFilter intentFilter = new IntentFilter(
"com.unique.name");
mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
//extract our message from intent
String msg_for_me = intent.getStringExtra("some_msg");
}
};
//registering our receiver
this.registerReceiver(mReceiver, intentFilter);
In your class add this to the part you want to notify the activity:
Intent i = new Intent("com.unique.name").putExtra("some_msg", "I have been updated!");
this.sendBroadcast(i);
You should use the observer / listener pattern.
http://www.vogella.com/articles/DesignPatternObserver/article.html
It is one of the most used design patterns when using MVC architecture pattern.
Your question is quite unclear but I think what you are wanting is to implement a callback to your activity. You can do this using an interface.
public class MwConsoleActivity extends Activity implements MwBondingAgent{
private classChild child = null;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
child = new classChild();
}
#Override
public void gotEventData(EventData myEventData) {
//to whatever you want with myEventData
}
}
And in your other class.
public class MwBondingAgent extends SapereAgent {
private MwBondingAgentCallback activityCallback;
MwBondingAgent(Activity callback){
activityCallback = callback;
}
public void AddEventListener(childAddedEvent event) {
//Send the data of event back to the main activity
EventData myEventData = //got some event data;
//Send it back to activity
activityCallback.gotEventData(myEventData);
}
public interface MwBondingAgentCallback {
public void gotEventData(EventData myEventData);
}
}

How to call a method in another activity

I have a question about communication between activities on implementation program of Android.
Here is two activity classes.
public class HelloAndroidActivity extends TabActivity{
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Resources res = getResources();
TabHost tabHost = getTabHost();
TabHost.TabSpec spec;
Intent intent;
intent = new Intent().setClass(this, Tab1Activity.class);
spec = tabHost.newTabSpec("Tab1").setIndicator(
"Tab1", res.getDrawable(R.drawable.ic_tab_icon))
.setContent(intent);
tabHost.addTab(spec);
}
}
_
public class Tab1Activity extends ListActivity {
private ArrayList<String> list = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
list = new ArrayList<String>();
setListAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, list));
addColumn("one");
addColumn("two");
addColumn("three");
}
public void addColumn(String s){
list.add(new String(s));
}
}
HelloAndroidActivity is main activity.
Tab1Activity is sub activity and display listview.
HelloAndroidActivity include Tab1Activity view.
What I want to do is calling addColumn method from HelloAndroidActivity,
because HelloAndroidActivity is added to new function like TwitterUserStreamAdapter.
If the android receive messages from internet,
application send message to Tab1Activity.
However, I don't know how to implement communication between activities.
You can pass data between activities using intent, you could put it in the extras with the intent:
HelloAndroidActivity
intent.putExtra("callX", true);
Tab1Activity
Bundle extras = getIntent().getExtras();
if (extras != null) {
boolean callX = extras.getBoolean("callX");
if(callX) {
X();
}
}
EDIT
If you need to event/listener mechanism it could be roughly like this(haven't compiled this, but should give you an idea):
public inerface MyEventListener {
abstract void handleMyEvent();
}
public class Tab1Activity implements MyEventListener {
public void handleMyEvent() {
/*...*/
}
protected void onCreate(Bundle savedInstanceState) {
/*...*/
HelloAndroidActivity.addListener(this);
}
protected void onDestroy() {
/*...*/
HelloAndroidActivity.removeListener(this);
}
}
public class HelloAndroidActivity {
static ArrayList<MyEventListener> listeners = new ArrayList<MyEventListener>();
public static void addListener(MyEventListener listener) {
listeners.add(listener);
}
public static void removeListener(MyEventListener listener) {
listeners.remove(m);
}
public static void onEvent() {
for(MyEventListener m : listeners) {
m.handleMyEvent();
}
}
}
although you can do it by creating static method , but not right way because it will leave context . pass data to Tab1Activity you have in HelloAndroidActivity throgh intent .
inside Tab1Activity getIntent and work accordingly .
you can also use onTabChange() to reflect changes between tabs .

Categories

Resources