SwipeRefreshLayout animation freezes onRefresh() - java

when I Swipe to Refresh the animation of SwipeRefreshLayout shows, but it is froze while onRefresh() runs, and only starts to spin when onRefresh() is finished.
MainActivity
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myFAB = (FloatingActionButton) findViewById(R.id.myFAB);
recyclerView = (RecyclerView) findViewById(R.id.rv);
recyclerView.setHasFixedSize(true);
LinearLayoutManager llm = new LinearLayoutManager(this);
recyclerView.setLayoutManager(llm);
recyclerView.addItemDecoration(new SimpleDividerItemDecoration(this));
callCadastroEncoemnda();
callPackageList();
swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipeRefreshLayout);
swipeRefreshLayout.setOnRefreshListener(this);
swipeRefreshLayout.setColorSchemeResources(
android.R.color.holo_blue_bright,
android.R.color.holo_green_light,
android.R.color.holo_orange_light,
android.R.color.holo_red_light);
}
onRefresh:
#Override
public void onRefresh() {
swipeRefreshLayout.setRefreshing(true);
Update.updateAll(MainActivity.this);
//Check if the data change
if (!packages.equals(dao.getPackages())) {
adapter.updateList(dao.getPackages());
}
swipeRefreshLayout.setRefreshing(false);
}

SOLVED!
I've put the refresh code on a Runnable:
(I've changed my refresh too)
#Override
public void onRefresh() {
new Thread(new Runnable() {
#Override
public void run() {
try {
if (Update.updateAll(MainActivity.this)) {
packages = dao.getPackages(config.getFilter());
packagesAux = dao.getPackages(config.getFilter());
runOnUiThread(new Runnable() {
#Override
public void run() {
adapter.animateTo(packages);
}
});
}
} catch (ExecutionException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
runOnUiThread(new Runnable() {
#Override
public void run() {
swipeRefreshLayout.setRefreshing(false);
}
});
}
}).start();
}

You don't need to have setRefreshing(true) statement in onRefresh() method.
When we drag the Ui downward, the spinning things starts itself automatically.
You just need to setRefreshing(false) to stop the spinner at the place where your desired result is achieved, but not in onRefresh().
For example, if you are hitting an api, we need to setRefreshing(false) at that point where we get the response from server i.e onPostExecute or similar.
Here is how I use it:
/**
* on Refreshing, fetch trip history again.
*/
#Override
public void onRefresh() {
fetchTripHistory();
}
#Override
public void onFailOfResponse(Object... arguments) {
mSwipeRefreshLayout.setRefreshing(false);
noDataText.setVisibility(View.VISIBLE);
}
};

#Override
public void onRefresh() {
.....
RVAdapterMain adapter = new RVAdapterMain(packages);
recyclerView.setAdapter(adapter);
....
}
.....
}
First of this seems like wrong. Could you please use it in onCreate(). And create the new method add the new data inside your adapter. When you refresh it onRefresh method only notifiyDataSetChanged() with new dataset instead of every time using the new adapter.

Related

Is there a way to refresh webView every x seconds?

Now I have this function for reload webView:
public void reloadWebView() {
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
webView.reload();
}
}, 5000);}
And it is called on onCreate function
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
reloadWebView();
}
The function works but it only runs once
Easy to solve as long as the Activity is running in foreground:
Handler handler = new Handler();
public void reloadWebView() {
handler.postDelayed(new Runnable() {
#Override
public void run() {
webView.reload();
reloadWebView();
}
}, 5000);}
Note that handler is now a field, out of reloadWebView().
Now call it in your onCreate():
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
reloadWebView();
}
Here is code to update your webview after x seconds
new CountDownTimer(5000, 1000) {
public void onTick(long millisUntilFinished) {
webView.reload();
//here you can have your logic to reload webview
}
public void onFinish() {
// hide progress bar if any
}
}.start();

textView is not updating while observer is running

I'm trying the LiveData and ViewModel architecture. I have a simple counter in the ViewModel which is observed on MainActivity. I am able to confirm that the data is acquired in onChanged of the observer, but the problem is the textView is not updating every increment and I'm only getting the last count which 9.
Here is my code.
MainActivity
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
binding.setNumber(model);
binding.setLifecycleOwner(this);
model = ViewModelProviders.of(this).get(MainActivityViewModel.class);
textView = findViewById(R.id.textView);
button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
try {
model.incrementNumber();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
model.getNumber().observe(this, new Observer<String>() {
#Override
public void onChanged(final String s) {
Log.d(TAG, s);
textView.setText(s);
}
});
}
And here is the viewModel
public class MainActivityViewModel extends AndroidViewModel {
MutableLiveData<String> number;
public MainActivityViewModel(#NonNull Application application) {
super(application);
number = new MutableLiveData<String>("0");
}
public MutableLiveData<String> getNumber(){
return number;
}
public void incrementNumber() throws InterruptedException {
for(int x = 0; x < 10 ; x++){
Thread.sleep(500);
number.setValue(String.valueOf(x));
}
}
}
Try using a main thread Handler.postDelayed that will increment the number and post again to the Handler instead of Thread.sleep.

ProgressDialog in runOnUiThread

I am trying to show progress dialog and update it inside runOnUiThread
but the progress bar never shown. when I replace the runOnUiThread with "new Thread" it work fine. But I want it to work with runOnUiThread
here is my code , I have deleted unnecessary codes
public class test extends Activity {
private ProgressDialog progress;
Handler progressBarHandler = new Handler();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
testing();
}
public void testing() {
progress=new ProgressDialog(this);
progress.setMessage("Saving Progress");
progress.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progress.setProgress(0);
progress.setMax(100);
progress.setCancelable(false);
progress.show();
runOnUiThread(new Runnable() {
#Override
public void run() {
//do some work
for (int i =0; i<100;i++){
//some work
progressBarHandler.post(new Runnable() {
#Override
public void run() {
progress.setProgress(finalCount);
}
});
}
}
}
Try this
public class MainActivity extends AppCompatActivity {
private ProgressDialog progress;
Handler workHandler;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
progress=new ProgressDialog(this);
progress.setMessage("Saving Progress");
progress.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progress.setProgress(0);
progress.setMax(100);
progress.setCancelable(false);
progress.show();
workHandler = new Handler(new HandlerThread("workHandlerThread").getLooper());
workHandler.post(new Runnable() {
#Override
public void run() {
//Do some work
runOnUiThread(new Runnable() {
#Override
public void run() {
progress.setProgress(/*work result*/);
}
});
}
});
}
}
The idea is you do the work on the HandlerThread bound to workHandler, and post the results back the the UI using runOnUiThread()

nullpointer exception java android

I need make a perfomclick() to execute the code below. There is a button called mButtonLogin, I need make perfomclick() when activity starts.
I have tried and read many Stackoverflow examples, but I can't make it work. log cat output it's a Nullpointer exception where I place the perfomclick().
Button mButtonLogin;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_story_post);
mButtonLogin = (Button)findViewById(R.id.button_login);
myclick();
}
public void loginExample()
{
// Login listener
final OnLoginListener mOnLoginListener = new OnLoginListener()
{
//stuff
};
final OnPublishListener onPublishListener = new SimpleFacebook.OnPublishListener()
{
//stuff
};
//More stuff Final too Called feed
mButtonLogin.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View view)
{
mSimpleFacebook.login(mOnLoginListener);
mSimpleFacebook.publish(feed, onPublishListener);
}
});
}
Why am I receiving a Nullpointer exception?
Try this:
//put this in the OnCreate
mButtonLogin = (Button)findViewById(R.id.button_login);
mButtonLogin.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mSimpleFacebook.login(mOnLoginListener);
mSimpleFacebook.publish(feed, onPublishListener);
}
});
// all your stuffs
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
mButtonLogin.performClick();
}

setcontent view in thread

I want to make a thread which will change the layout of my activity ... I have 2 layouts : welcomepage and activity_main ...
The goal of thread: when I launch my application , the welcomepage layout will be visible in only 5 sec and after that the layout again will be activity_main ...
I wrote the code as below:
package com.example.tripolimazad;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.TextView;
public class MainActivity extends Activity {
public TextView counter = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.welcomepage);
counter = (TextView) findViewById(R.id.Counter);
Thread th=new Thread(){
#Override
public void run(){
try
{
Thread.sleep(10000);
setContentView(R.layout.activity_main);
}catch (InterruptedException e) {
}
}
};
th.start();
}
#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;
}
}
but it doesnt work !!! have anyone any solution plz !
You cannot change the UI on a non-UI thread, however in an Activity, you can use the runOnUiThread method:
runOnUiThread(new Runnable() {
#Override
public void run() {
setContentView(R.layout.activity_main);
}
});
This seems very strange though, to have this in your onCreate.
You may also try to use CountDownTimer something like:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.welcomepage);
//display the logo during 5 secondes,
new CountDownTimer(5000,1000){
#Override
public void onTick(long millisUntilFinished){}
#Override
public void onFinish(){
//set the new Content of your activity
MainActivity.this.setContentView(R.layout.main);
}
}.start();
//...
}
See Displaying logo for few seconds at application start for more.
Alternatively you can use a handler to avoid creating a new thread as following:
getWindow().getDecorView().getHandler().postDelayed(new Runnable() {
#Override public void run() {
setContentView(R.layout.activity_main);
}
}, 10000);
UI related operations must be done on UI thread only and must not be done in non-UI thread as you are doing. But you can update UI from non-UI thread as follows:
activityContext.runOnUiThread(new Runnable() {
#Override
public void run() {
setContentView(R.layout.activity_main);
}
});
However a better approach for the situation you mentioned is to use an Async task, provided by the Android.You can try following :
/*
* Activity/Thread to display the **welcomepage**
* when the app is started.
*/
public class SplashActivity extends Activity {
// how long until we go to the next activity
protected int _splashTime = 5000; // 5 seconds
// thread to display welcome page
private Thread splashTread;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.your_welcome_page_layout);
// thread for displaying the WelcomeScreen
splashTread = new Thread() {
#Override
public void run() {
try {
synchronized (this) {
// wait 5 sec
wait(_splashTime);
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
// finish the current splashactivity
finish();
// start MainActivity as next activity
startActivity(new Intent(SplashActivity.this, MainActivity.class));
}
}
};
// start the thread.
splashTread.start();
}
}

Categories

Resources