I have SurfaceView and Run() method , Its like a loop , how can i edit textView text in this Run method ?
I wrote :
textView1.setText("my text");
It didn't work ? any Ideas ?
the code summary is :
public class GFXSurface extends Activity {
MySurface ourSurfaceView;
TextView textView1;
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(ourSurfaceView);
}
public class MySurface extends SurfaceView implements Runnable{
#Override
public void run() {
//here i want to edit textView1
}
}
}
You cannot alter Views that were initialized on the main thread from another thread. You should look into using a Handler to post on the UI thread. It wouldn't be wise to update a TextView inside that run method either, but I'm not sure what you're trying to accomplish exactly.
You can try setting text to your TextView using the runOnUiThread() method call, for example the following:
runOnUiThread(new Runnable(){
public void run() {
//here set the textview content
}
});
Related
Hey I am trying to get real time data change in the main activity in my custom view. I want to implement a listener for the view, such that whenever anything changes in my Main Activity, my View gets to know about that and act accordingly.
Following is in my Main Activity.
public void setChangeListener(OnChangeListener onChangeListener){
this.onChangeListener = onChangeListener;
}
public interface OnChangeListener{
void currentRadius(int r);
void currentSpeed(int s);
}
I have initialized the same in View as,
public CustomView extends View{
//CONSTRUCTORS
//EVERYTHING ELSE
//These are inside the init(Context context) method.
MainActivity mainActivity = new MainActivity();
mainActivity.setOnChangeListener(new MainActivity.OnChangeListener() {
#Override
public void currentR(int r) {
Log.d("R", ""+r);
}
#Override
public void currentS(int s) {
Log.d("S", ""+s);
}
});
}
But this is giving me NullPointerException at
onChangeListener.currentR(//INTEGER VALUE);
onChangeListener.currentS(//INTEGER VALUE);
which are inside a onProgressChanged Listener.
What I want to ask is that is it even possible to send data using Listeners from Activity to View? If yes, then any pointers would be appreciated. Thanks.
In MainActivity
CustomView mCustomeView = new CustomView(this); // or Resource id
Create methods in CustomView
public void currentR(int r) {
Log.d("R", ""+r);
}
public void currentS(int s) {
Log.d("S", ""+s);
}
Then call that methods from MainActivity
mCustomeView.currentR(integervalue);
mCustomeView.currentS(integervalue);
NOTE:Be sure that if you change UI from that methods. It will be in Main UI Thread . other wise it will throw error
Hope This help
MainActivity mainActivity = new MainActivity();
Do not instantiate an Activity. Pass MainActivity context to the view and use that to do operations.
sample context
Context context = MainActivty.this;
There is an int value that continuously get updated inside a thread and I want to show the value in a textview but i m unable to use findviewbyid inside of thread ?
How to refer to that textview from inside that thread and update it accordingly?
Here is my code:
package com.example.raj.testview;
import android.widget.TextView;
public class TextChange implements Runnable
{
public void run()
{
TextView tv=(TextView)findViewById(R.id.tv);
for(int i=0;i<10000;i++)
{
tv.setText(String.valueOf(i));
}
}
}
You cannot change UI elements from a non-UI thread. Try using runOnUiThread.
runOnUiThread(new Runnable(){
#Override
public void run(){
// change UI elements here
}
});
I have a Class: GalleryLoop which contains all the details
I have a separate Class: LoadingScreenActivity that has an inner class that extends AsyncTask
I am trying to call the .execute in LoadingScreenActivity such that i could load the GalleryLoop
Is there any way i can execute without combining both Java CLass files?
The codes are as follows:
private class LoadViewTask extends AsyncTask<Void, Integer, Void>
{
//A TextView object and a ProgressBar object
private TextView tv_progress;
private ProgressBar pb_progressBar;
//Before running code in the separate thread
#Override
protected void onPreExecute()
{
//Initialize the ViewSwitcher object
viewSwitcher = new ViewSwitcher(LoadingScreenActivity.this);
/* Initialize the loading screen with data from the 'loadingscreen.xml' layout xml file.
* Add the initialized View to the viewSwitcher.*/
viewSwitcher.addView(ViewSwitcher.inflate(LoadingScreenActivity.this, R.layout.loadingscreen, null));
//Initialize the TextView and ProgressBar instances - IMPORTANT: call findViewById() from viewSwitcher.
tv_progress = (TextView) viewSwitcher.findViewById(R.id.tv_progress);
pb_progressBar = (ProgressBar) viewSwitcher.findViewById(R.id.pb_progressbar);
//Sets the maximum value of the progress bar to 100
pb_progressBar.setMax(100);
//Set ViewSwitcher instance as the current View.
setContentView(viewSwitcher);
}
//The code to be executed in a background thread.
#Override
protected Void doInBackground(Void... params)
{
/* This is just a code that delays the thread execution 4 times,
* during 850 milliseconds and updates the current progress. This
* is where the code that is going to be executed on a background
* thread must be placed.
*/
try
{
//Get the current thread's token
synchronized (this)
{
//Initialize an integer (that will act as a counter) to zero
int counter = 0;
//While the counter is smaller than four
while(counter <= 4)
{
//Wait 850 milliseconds
this.wait(850);
//Increment the counter
counter++;
//Set the current progress.
//This value is going to be passed to the onProgressUpdate() method.
publishProgress(counter*25);
}
}
}
catch (InterruptedException e)
{
e.printStackTrace();
}
return null;
}
//Update the TextView and the progress at progress bar
#Override
protected void onProgressUpdate(Integer... values)
{
//Update the progress at the UI if progress value is smaller than 100
if(values[0] <= 100)
{
tv_progress.setText("Progress: " + Integer.toString(values[0]) + "%");
pb_progressBar.setProgress(values[0]);
}
}
//After executing the code in the thread
#Override
protected void onPostExecute(Void result)
{
/* Initialize the application's main interface from the 'main.xml' layout xml file.
* Add the initialized View to the viewSwitcher.*/
viewSwitcher.addView(ViewSwitcher.inflate(LoadingScreenActivity.this, R.layout.main, null));
//Switch the Views
viewSwitcher.showNext();
//ImageView = viewSwitcher.findViewById(R.id.imageView1);
setContentView(R.layout.main);
}
}
The other class file:
public class GalleryLoop extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//details of Galleryloop
}
I am new to Android and I am not sure which of the following would be a better choice:
1.By initiating the GalleryLoop before the AsyncTask starts
2.Initiating the GalleryLoop within the AsyncTask (in the do_in_background)
Thanks in advance.
My answer to this post should help you... Use a constructor for the Asynctask class and pass the calling activity to the Asynctask...
Then you can call a callback function in the calling activity once Asynctask is finished.
This should allow you to use one class for your GalleryLoop activity and run the loading screen activity using Asynctask in the background, calling a callback function when complete.
This maybe a stupid idea, but does anyone know is it possible to access one activity's object form other places?
To be specific, lets say if you have an activity A (with a textView t) and you create a normal java class B.
At onCreate, you start to run B for some calculation like below,
public class MyActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
t = (TextView)findViewById(R.id.outputtext);
Somejava B = new Somejava();
B.run();
}
}
Is there a way for B to update the textView?
I know the simple way (maybe the correct way) is to return the result from B class and use t.setText(result) in MyActivity, but I'm just want to know is it possible to update the textview in B?
Use Intent or public static variables
can simply pass activity refernce to b in constructor and create the method in your acitivty to update textview. if you using another thread not forgot to use handler or other ways to update UI thread.
Yes, it is possible if the Activity's field is public and post the UI changes in a public Handler created on the first Activity but in facts, it's really ugly to do that...
You can use startActivityForResult(...) to notify an other activity how the process has passed with some serialiezable data in the Bundle extras of the Intent and catch the result in the overrided method onActivityResult(...)...
For a "normal java class" B I would work with interfaces
public interface SomejavaListener{
void onSomejavaFinish(Object result);
}
public class MyActivity implements SomejaveFinish extends Activity {
TextView t;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
t = (TextView)findViewById(R.id.outputtext);
Somejava B = new Somejava();
B.run(MyActivity.this); //notice the extra argument!
}
public void onSomejavaFinish(Object result){
t.setText("updated! ^,^");
}
}
public class Somejava {
//...
public void run(SomejavaListener callback){
//working working
callback.onSomejavaFinish( new Object() );
}
}
However in respect to the android environment the question is sitting in I got the feeling maybe an AsyncTask would be the right thing for you. It has an doInBackground method to do work and not spoiling your UI Thread (resulting in ANR Errors.)
Another advantage is the onPreExecute and onPostExecute methods are running in the UI Thread itself again, so it just takes a blink to update your TextView
public class MyActivity extends Activity {
TextView t;
private class MyAsyncTask extends AsyncTask<Void, Void, Void> {
protected Void doInBackground(Void... void) {
//do your stuff
return null
}
protected void onPostExecute(Void void) {
MyActivity.this.t.setText("updated ^^v");
}
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
t = (TextView) findViewById(R.id.outputtext);
MyAsyncTask myAsyncTask = new MyAsyncTask();
myAsyncTask.execute();
}
}
I am having problem with setting a new Drawable to my ProgressBar.
If I use the setProgressDrawable() inside onCreate() method it works great. But when I try to call the same method inside a Handler post callback it doesn't work and the progressbar disapears.
Can someone explain this behaviour? How can I solve this problem?
downloadingBar.setProgress(0);
Drawable progressDrawable = getResources().getDrawable(R.drawable.download_progressbar_pause_bg);
progressDrawable.setBounds(downloadingBar.getProgressDrawable().getBounds());
downloadingBar.setProgressDrawable(progressDrawable);
downloadingBar.setProgress(mCurrentPercent);
First you should reset the progress to zero
Set the progress drawable bounds
Set new progress drawable
Set new progress
Bumped into this problem myself and I managed to get it working :)
I used the AsyncTask to handle the background tasks/threads, but the idea should be the same as using Runnable/Handler (though AsyncTask does feel nicer imo).
So, this is what I did... put setContentView(R.layout.my_screen); in the onPostExecute method! (ie. instead of the onCreate method)
So the code looks something like this:
public class MyScreen extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.my_screen); !!! Don't setContentView here... (see bottom)
new MySpecialTask().execute();
}
private int somethingThatTakesALongTime() {
int result;
// blah blah blah
return result;
}
private void updateTheUiWithResult(int result) {
// Some code that changes the UI
// For exampe:
TextView myTextView = (TextView) findViewById(R.id.result_text);
myTextView.setText("Result is: " + result);
ProgressBar anyProgressBar = (ProgressBar) findViewById(R.id.custom_progressbar);
anyProgressBar.setProgressDrawable(res.getDrawable(R.drawable.progressbar_style));
anyProgressBar.setMax(100);
anyProgressBar.setProgress(result);
}
private class MySpecialTask extends AsyncTask<String, Void, Integer> {
ProgressDialog mProgressDialog;
#Override
protected void onPreExecute() {
mProgressDialog = ProgressDialog.show(MyScreen.this, "", "Calculating...\nPlease wait...", true);
}
#Override
protected Integer doInBackground(String... strings) {
return somethingThatTakesALongTime();
}
#Override
protected void onPostExecute(Integer result) {
mProgressDialog.dismiss();
setContentView(R.layout.my_screen); // setContent view here... then it works...
updateTheUiWithResult(result);
}
}
}
To be honest, why you need to call setContentView in onPostExecute I have no idea... but doing so means you can set custom styles for your progress bars (and they don't disappear on you!)
Maybe you put the code in a thread which is not main thread.
If you want to work with the UI, you must do that in the main thread :)
I was also facing the same issue but in my case it is due to the use of Drawable.mutate() method. When i removed that method it started working fine. I also noticed that this issue exist below api level-21(lollipop).