My android application has two intents.
First one: main window,
second one contains the game view (SurfaceView).
When user push "return" button, main windows appears before the game view indent suspends (surfaceDestroyed).
However I need to run a method in game view before the main windows appears. I've stuck with this question.
Here code:
MainWindow class:
#Override
public void onClick(final View v) {
if (v.getId() == R.id.StartBtn) {
final Intent myIntent = new Intent(getApplicationContext(),
StartActivity.class);
this.startActivity(myIntent);
}
}
StartActivity class
public class StartActivity extends Activity {
#Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_start);
}
#Override
protected void onPause() {
super.onPause();
}
#Override
protected void onSaveInstanceState(final Bundle outState) {
super.onSaveInstanceState(outState);
}
GameView class
public class GameView extends SurfaceView implements SurfaceHolder.Callback {
#Override
public void surfaceDestroyed(final SurfaceHolder arg0) {
//Do some operations before destroing
}
}
Layout activity_start
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".StartActivity" >
<com.somepackage.appname.GameView
android:id="#+id/game_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
So I need to start surfaceDestroyed in GameView before onResume on MainWindow intent
i am not sure if that is really what yiu are looking for, but i will give it a try:
You need to have an instance inside the other Activity before you can call any method there. You can achieve it by using this:
(OtherActivity) getActivity.myMethod();
Use Activity.this instead of getApplicationContext(). That May be the problem. If not please provide the code.
simply use
Intent intent = new Intent(MainAWindow.this,StartActivity.class);
startActivity(intent);
and where is ur OnResume method?... explain your question properly what u want to achieve exactly..?
Related
I'm trying to update a TextView object's text by calling the setText() method. I provide a string value directly to it, but I can't get it to update on the UI of the app running on the Emulator.
This is taking place on a fragment (one of the fragments automatically generated when a project with a simple activity is created on Android Studio)
A couple points about my situation thus far:
I tried calling the setText() method with the runOnUiThread "pattern" to no avail.
getActivity().runOnUiThread(new Runnable()
{
#Override
public void run()
{
textView.setText("Service online");
}
});
I checked property mText of the TextView instance. It IS UPDATED. It just doesn't update on the UI :/
In short, no matter what I try to do, the UI element sticks to whatever string value is set on the XML Fragment file (or no value, if I delete the android:text attribute). Other posts on Stack Overflow similar to this issue did not help me either. Any idea what it could be?
Also, I'm posting the entire fragment related java code:
public class FirstFragment extends Fragment
{
public Gson serializer;
public TextView textView;
private NetworkManager networkManager;
private boolean serviceIsBound;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_first, container, false);
textView = (TextView) view.findViewById(R.id.main_window);
textView.setText(R.string.app_name);
return inflater.inflate(R.layout.fragment_first, container, false);
}
#Override
public void onStart() {
super.onStart();
Intent bindIntent = new Intent(getActivity(), NetworkManager.class);
getActivity().bindService(bindIntent, serviceConnection, Context.BIND_AUTO_CREATE);
}
#Override
public void onStop()
{
super.onStop();
getActivity().unbindService(serviceConnection);
serviceIsBound = false;
}
public void onViewCreated(#NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
view.findViewById(R.id.button_first).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Log.v("DEV UPDATE", "Starting Request ");
if (serviceIsBound)
{
GetAPIStatusResult result = networkManager.GetAPIStatus();
if (result.GetStatus())
{
Log.v("REQUEST RESULT", "API is Fine");
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
textView.setText("Service online");
}
});
}
else
{
Log.v("REQUEST RESULT", "API is Down or a problem occurred");
textView.setText("Service down");
}
}
}
});
}
private ServiceConnection serviceConnection = new ServiceConnection()
{
#Override
public void onServiceConnected(ComponentName className, IBinder service)
{
NetworkManager.NetworkManagerServiceBinder binder = (NetworkManager.NetworkManagerServiceBinder) service;
networkManager = binder.GetService();
serviceIsBound = true;
}
#Override
public void onServiceDisconnected(ComponentName arg)
{
serviceIsBound = false;
}
};
}
The associated XML for the fragment:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".FirstFragment">
<TextView
android:id="#+id/main_window"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Here will appear API status"
app:layout_constraintBottom_toTopOf="#id/button_first"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="#+id/button_first"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="SendRequest"
android:text="#string/SendRequest"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/main_window" />
</androidx.constraintlayout.widget.ConstraintLayout>
As user Cheticamp commented, I had an issue on my onCreateView() method, where I was calling the infalter.inflate() method twice, and not returning my view object.
I replaced the second inflate() method call with a return of my view object and it immediately worked! My UI was now being updated as expected!
You're trying to reference a view that belongs to the activity. If you want to update something in the activity you need to look at other methods rather than trying to directly reference the views.
A good place to start would be an interface you pass to the fragment that is created by the activity. Call the interface method from the fragment when you want to set the next. Then let the activity handle the updating. This is cleaner too as each view is responsible for its own elements only.
You also don't need to use runOnUIThread as onViewCreated isn't an ansychronos function you're already on the UI thread anyway.
Hopefully that helps.
I call a view class from my activity. Then the view class calls the same activity. Here is the problem, once the activity comes back up, it won't register any more button pushes.(I'm trying to call another view class. Here is some code:
View Class
public class AnimationView extends View {
Activity myActivity;
//...
public AnimationView(Context context, Activity activity) {
super(context);
//...
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//...
myActivity.setContentView(R.layout.activity_home);
}
}
Home Activity
public class HomeActivity extends AppCompatActivity {
private AnimationView mDrawViewA;
///...
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
mDrawViewA = new AnimationView(this,this);
start = (Button) findViewById(R.id.startButton);
//...
start.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//...
setContentView(mDrawViewA);
//calls more views
//......
});
}
I realize now maybe I should have been calling the view classes in different activities, but I would very much like a get all the view classes working within the same activity.
The problem is you're calling setContentView every time you press the "start" button. This method will overwrite the current layout (if any) with the new value you're setting.
What you can do to get the result you're expecting, which, from what I understand, is to add a new AnimationView to your current layout on every button click, you can try something like this:
start.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
AnimationView animationView = new AnimationView(getApplicationContext());
// I'm using ConstraintLayout as an example, since I don't know exactly what layout you're using
ConstraintLayout.LayoutParams params = new ConstraintLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT);
// Set the layout params the way you want
addContentView(animationView, params); // This is where the magic happens
}
});
In short, addContentView is the method you should use when you want to add new views into your activity's root layout.
PS.: It's a terribly bad practice to let the views "know" the activity controlling it. It's always the opposite way around: the activity/fragment knows the view(s) it's controlling.
I am trying to make a button on my homepage of an app that will lead to a search page, that will have a handful more buttons leading to other pages. However, I used the same code from my activity main for the button in my second page (seachpage) and now when I run the code, my first button on my main page, when clicked it just shuts the app down. I don't even know how to approach this properly because I copied the same code, just changed the "findViewById" and the "startActivity" accordingly with their new labels. Any recommendation or help would be massively appreciated!
Activity main Java code:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button yourButton = (Button) findViewById(R.id.TranslateButton);
if (yourButton == null) throw new AssertionError();
yourButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
startActivity(new Intent(MainActivity.this, SearchPage.class));
}
});
}
}
Activity main xml for the button:
Secondary page (searchpage) Java code:
public class SearchPage extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search_page);
Button accommodationButton = (Button) findViewById(R.id.accommodationButton);
if (accommodationButton == null) throw new AssertionError();
accommodationButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
startActivity(new Intent(SearchPage.this, Accommodation.class));
}
});
}
}
Secondary page xml for the button:
<Button
android:layout_width="match_parent"
android:layout_height="0dp"
android:text="#string/accommodation"
android:id="#+id/accommodationButton"
android:layout_below="#+id/search_bar"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_weight="1"/>
Thank you again for taking the time and consideration to read and/or respond to my question~!
Over the past days I've desperately been trying to build an android app with a simple fragment (which I use twice). I want to pass the contents of the fragments' EditText-boxes to a new activity. I just can't figure out how to get those contents from the fragments. What I have so far is this:
I've got my edit_text_fragment.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<EditText
android:id="#+id/my_edit_text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:hint="my hint" />
</LinearLayout>
and the corresponding MyEditTextFragment.java:
public class MyEditTextFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.edit_text_fragment, container, false);
return view;
}
}
I then use this fragment twice in my main.xml like this:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<fragment
android:id="#+id/detailfragment_placeholder"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
class="com.example.fragmenttester5.MyEditTextFragment" />
<fragment
android:id="#+id/detailfragment_placeholder2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
class="com.example.fragmenttester5.MyEditTextFragment" />
<Button
android:id="#+id/submit_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Submit all of it" />
</LinearLayout>
and in my MainActivity I hooked up the button to a new activity:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button submitButton = (Button) findViewById(R.id.submit_button);
submitButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v){
Intent intent = new Intent(MainActivity.this, OtherActivity.class);
intent.putExtra("result1", "the_result_from_the_first_editText");
intent.putExtra("result2", "the_result_from_the_second_editText");
startActivity(intent);
}
});
}
}
I think I now need to define some kind of interface in the Fragment, but I can't find how. I read a couple examples and tutorials (like this one), but they make no sense to me at all. I don't understand the code given and I just don't understand how to adjust it for my use case.
So my question; can anybody help me to get the contents of the fragment from within the activity? Examples would be very very welcome since I'm just banging my head against the wall here..
You are right, that's kind of a standard way to pass data from a Fragment to an activity.
Basically you define a Listener interface which the Activity implements, and the Activity registers itself as a Listener with the Fragment.
Here's a simple example:
Fragment
class MyFragment extends Fragment {
interface Listener {
public void somethingHappenedInFragment(Object... anyDataYouWantToPassToActivity);
}
private Listener mListener;
public void setListener(Listener listener) {
mListener = listener;
}
// ... your code ...
// Now here you pass the data to the activity
mListener.somethingHappenedInFragment(some, data);
// ... more of your code
}
Activity
public MyActivity extends Activity implements MyFragment.Listener {
// ... your code ...
// creating the Fragment
MyFragment f = new MyFragment();
// register activity as listener
f.setListener(this);
// ... more of your code
// implementation of MyFragment.Listener interface
#Override
public void somethingHappenedInFragment(Object... anyDataYouWantToPassToActivity) {
// here you have the data passed from the fragment.
for (Object o : anyDataYouWantToPassToActivity {
System.out.println(o.toString();
}
}
}
On a high level, there are two tasks that you commonly need to solve with Fragments. The first is communicating data from an Activity to a Fragment. The second is communicating data from a Fragment to an Activity.
An Activity knows which Fragments it contains since it creates them, so it's easy to communicate that way - just call methods on the Fragment itself. But the inverse is not true; Fragments might be attached to any number of random Activities, so it doesn't know anything about it's parent.
The solution is to implement an interface that the Activity implements and the Fragment knows how to communicate with. That way, your Fragment has something it knows how to talk with. There are specific code examples for how to do it here: http://developer.android.com/guide/components/fragments.html#CommunicatingWithActivity
(In particular, check out the "Creating event callbacks to the activity" code examples).
So you'd create an Interface to talk with the Activity if the event happened in the Fragment. For situations like this, you can simply make an accessible method in the Fragment that the Activity can call. So
public class MyEditTextFragment extends Fragment {
private EditText mEditText;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.edit_text_fragment, container, false);
return view;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mEditText = (EditText) getView().findViewById(R.id.my_edit_text);
}
public Editable getText() {
return mEditText.getText();
}
}
Then
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final MyEditTextFragment fragment1 = (MyEditTextFragment)
getFragmentManager().findFragmentById(R.id.detailfragment_placeholder);
final MyEditTextFragment fragment2 = (MyEditTextFragment)
getFragmentManager().findFragmentById(R.id.detailfragment_placeholder2);
Button submitButton = (Button) findViewById(R.id.submit_button);
submitButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v){
String firstResult = fragment1.getText().toString();
String secondResult = fragment2.getText().toString();
Intent intent = new Intent(MainActivity.this, OtherActivity.class);
intent.putExtra("result1", firstResult);
intent.putExtra("result2", secondResult);
startActivity(intent);
}
});
}
}
This assumes that you assigned the Fragment tags in your FragmentTransaction. Be sure to check for null Fragments (omitted for brevity)
Activity will be received data from updateDetail() method in Fragment
//// Activity
public class RssfeedActivity extends Activity implements MyListFragment.OnItemSelectedListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_rssfeed);
Button btn = (Button) findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d("Annv - Fragment", "onClick here");
}
});
}
// if the wizard generated an onCreateOptionsMenu you can delete
// it, not needed for this tutorial
#Override
public void onRssItemSelected(String link) {
// DetailFragment fragment = (DetailFragment) getFragmentManager()
// .findFragmentById(R.id.detailFragment);
// if (fragment != null && fragment.isInLayout()) {
// fragment.setText(link);
// }
// Intent start = new Intent(this, RssfeedSecondActivity.class);
// startActivity(start);
DetailFragment fragment = (DetailFragment) getFragmentManager()
.findFragmentById(R.id.detailFragment);
if (fragment != null && fragment.isInLayout()) {
fragment.setText(link);
}
}
}
/// Fragment
public class MyListFragment extends Fragment {
private OnItemSelectedListener listener;
private OnItemStartActivityListener listenerStartAct;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_rsslist_overview,
container, false);
Button button = (Button) view.findViewById(R.id.button1);
Log.d("Annv - Fragment", "run on " + getActivity().toString());
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
updateDetail();
}
});
return view;
}
public interface OnItemSelectedListener {
public void onRssItemSelected(String link);
}
public interface OnItemStartActivityListener {
public void onRssStartActivity(String link);
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (activity instanceof OnItemSelectedListener) {
Log.d("Annv - Fragment", "activity " + activity.getLocalClassName());
listener = (OnItemSelectedListener) activity;
} else if (activity instanceof OnItemStartActivityListener) {
Log.d("Annv - Fragment", "activity " + activity.getLocalClassName());
listenerStartAct = (OnItemStartActivityListener) activity;
} else {
throw new ClassCastException(activity.toString()
+ " must implemenet MyListFragment.OnItemSelectedListener");
}
}
// May also be triggered from the Activity
public void updateDetail() {
// create fake data
// String newTime = String.valueOf(System.currentTimeMillis());
// // Send data to Activity
// listenerStartAct.onRssItemSelected(newTime);
if (getActivity() instanceof OnItemSelectedListener) {
listener.onRssItemSelected("start start");
} else {
String newTime = String.valueOf(System.currentTimeMillis());
listenerStartAct.onRssStartActivity(newTime);
}
}
}
So I have this code in my main activity to start a new one:
public class MainActivity extends Activity
{
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
findViewById(R.id.GoButton).setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
Intent myIntent = new Intent(MainActivity.this, NewActivity.class);
MainActivity.this.startActivity(myIntent);
//finish();
}
});
}
}
My new activity extends ListActivity and when I call this code by pressing the button it crashes the application. However if I make the MainActivity extend ListActivity then it works great (although I have to replace the button with a List!). Does anyone know why this happens, and how can I make it work using the code above?
Thanks
Have you added the manifest entry