How to get to next object in foreach - android

Im making a quizz app in android studio.I have a slight issue. I display the questions and answers fine, but when the user click on a button, be it right or wrong answer, i want the next question to come.
I feel its really stupid, but heres what i did.
private void getListe() {
new Thread(new Runnable() {
#Override
public void run() {
QuizzController quizzController = new QuizzController(GameActivity.this);//bon contexte?
liste = quizzController.getGame(difficulte, categorie, nb);
handlerGame.post(new Runnable() {
#Override
public void run() {
Toast.makeText(GameActivity.this,"gg", Toast.LENGTH_SHORT).show();
for(QuizzRoom q : liste ){
tvQuestion.setText(q.question);
btnBadAnswer.setText(q.mauvaisesReponses);
btnGoodAnswer.setText(q.bonneReponse);
}
btnGoodAnswer.setOnClickListener(v -> {
score+=10;
tvScore.setText(String.valueOf(score));
});
}
});
}
}).start();private void getListe() {
new Thread(new Runnable() {
#Override
public void run() {
QuizzController quizzController = new QuizzController(GameActivity.this);//bon contexte?
liste = quizzController.getGame(difficulte, categorie, nb);
handlerGame.post(new Runnable() {
#Override
public void run() {
Toast.makeText(GameActivity.this,"gg", Toast.LENGTH_SHORT).show();
for(QuizzRoom q : liste ){
tvQuestion.setText(q.question);
btnBadAnswer.setText(q.mauvaisesReponses);
btnGoodAnswer.setText(q.bonneReponse);
}
btnGoodAnswer.setOnClickListener(v -> {
score+=10;
tvScore.setText(String.valueOf(score));
});
}
});
}
}).start();
I cannot figure how to get to the next QuizzRoom object (answer+questions). Feels like it should just come right on when the loop starts over, but it doesnt.
Thanks in advance for any tips in the right direction.

This is not the best way but it should work:
private int questionsCount;
new Thread(new Runnable() {
#Override
public void run() {
QuizzController quizzController = new QuizzController(GameActivity.this);//bon contexte?
liste = quizzController.getGame(difficulte, categorie, nb);
//get the size of the list
questionsCount = liste.size()
handlerGame.post(new Runnable() {
#Override
public void run() {
Toast.makeText(GameActivity.this,"gg", Toast.LENGTH_SHORT).show();
btnGoodAnswer.setOnClickListener(v -> {
score+=10;
//will remove the last question form the count
questionsCount--
tvScore.setText(String.valueOf(score));
showQuestion(liste)
});
}
});
}
}).start();
void showQuestion(List<QuizzRoom> questions){
//here you should check if there are any questions left
// if(questionsCount < 0) do something
QuizzRoom q = questions[questionsCount]
tvQuestion.setText(q.question);
btnBadAnswer.setText(q.mauvaisesReponses);
btnGoodAnswer.setText(q.bonneReponse);
}

Related

How to perform click continuously while something is enable

I'm beginner... I need to run some code after 10 seconds continuously while my button is enable.
and when I clicked on it and it turned to disable-state, timer get stop.
I use below code but it run just once when I click on timerbutton every time again...
I think I have to use threed and I think I used it too! But I did not get to my goal.
private View.OnClickListener ontimerclicked = new View.OnClickListener() {
#Override
public void onClick(View view) {
Handler myHandler = new Handler();
myHandler.postDelayed(new Runnable() {
#Override
public void run() {
if (endistimer==false) {
endistimer=true;
varbtnimgslidtimer.setBackgroundColor(Color.parseColor("#E91E63"));
varbtnimgnext.performClick();
intdelay=10000;
}
else
{
endistimer=false;
varbtnimgslidtimer.setBackgroundColor(Color.parseColor("#dddddd"));
intdelay=0;
}
}
}, intdelay);
}
};
I finaly solved it with below code.I put it for anothers:
private View.OnClickListener ontimerclicked = new View.OnClickListener() {
#Override
public void onClick(View view) {
mHandler = new Handler();
if (endistimer==false) {
endistimer=true;
varbtnimgslidtimer.setBackgroundColor(Color.parseColor("#E91E63"));
}
else
{
endistimer=false;
varbtnimgslidtimer.setBackgroundColor(Color.parseColor("#dddddd"));
intdelay=5000;
cntsec=0;
varbtnplusfive.setText(arrsec[0] +" Sec");
}
new Thread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
while (endistimer) {
try {
Thread.sleep(intdelay);
mHandler.post(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
// your codes
// you can set continue_or_stop to false, for stop
}
});
} catch (Exception e) {
// TODO: handle exception
Toast.makeText(slideword.this,e.toString(),Toast.LENGTH_SHORT);
}
}
}
}).start();
}
};

Android remove all recyclerview with animation on a button click

I have a recycler view. On a button click I want to remove all the items from the recyclerview but the items must be removed with animation.
I am able to remove all the items at once but I don't know how to remove them with animation. Thanks
It's old, but wish this helps someone else as it's already not answered yet; I have done it by deleting a single item at a time by simulating a swipe animation on this item, and post a delay before deleting the next item, and so on to the way down to the last item of the RecyclerView
Step No.1:
In your activity that holds the clear all button and the RecyclerView instance: Create a method of single item delete
private void deleteItem(View rowView, final int position) {
Animation anim = AnimationUtils.loadAnimation(requireContext(),
android.R.anim.slide_out_right);
anim.setDuration(300);
rowView.startAnimation(anim);
new Handler().postDelayed(new Runnable() {
public void run() {
if (myDataSource.size() == 0) {
addEmptyView(); // adding empty view instead of the RecyclerView
return;
}
myDataSource.remove(position); //Remove the current content from the array
myRVAdapter.notifyDataSetChanged(); //Refresh list
}
}, anim.getDuration());
}
Step No.2:
Create the method that will delete all RecyclerView list items >> call it in your button click callback.
boolean mStopHandler = false;
private void deleteAllItems() {
final Handler handler = new Handler();
Runnable runnable = new Runnable() {
#Override
public void run() {
if (myDataSource.size() == 0) {
mStopHandler = true;
}
if (!mStopHandler) {
View v = myRecyclerView.findViewHolderForAdapterPosition(0).itemView;
deleteItem(v, 0);
} else {
handler.removeCallbacksAndMessages(null);
}
handler.postDelayed(this, 250);
}
};
requireActivity().runOnUiThread(runnable);
}
Also it's important to handle configuration change in manifest, activity section, as if the configuration changes while clearing your recycler view list, an exception will be raised
<activity
android:name=".activities.MainActivity"
android:configChanges="orientation|screenSize|keyboard"
android:label="#string/app_name">
...
</activity>
This is a pretty good library and what's better is the documentation for it. You can even insert durations for transitions and animations.
Also, remember that if you are using default animation, after calling myDataSet.remove(pos) using adapter.notifyDataSetChanged() while there is an animation ongoing will cause the animation to stop.
Extend BaseItemAnimator class of recyclerview-animators library:
MyAdapter adapter = new MyAdapter(null);
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.setAdapter(adapter);
recyclerView.setItemAnimator(new MyScaleInLeftAnimator());
findViewById(R.id.button).setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View view) {
int count = adapter.getItemCount();
adapter.clear();
adapter.notifyItemRangeRemoved(0, count);
}
}
);
...
public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder{
private ArrayList<String> mItems;
...
public void clear() {
if (mItems != null) {
mItems.clear();
}
}
}
...
public class MyScaleInLeftAnimator extends BaseItemAnimator {
private long lastRemoval;
private int removeCount;
public MyScaleInLeftAnimator() {
lastRemoval = 0;
removeCount = 0;
}
public MyScaleInLeftAnimator(Interpolator interpolator) {
mInterpolator = interpolator;
lastRemoval = 0;
removeCount = 0;
}
#Override protected void preAnimateRemoveImpl(RecyclerView.ViewHolder holder) {
ViewCompat.setPivotX(holder.itemView, 0);
}
#Override protected void animateRemoveImpl(final RecyclerView.ViewHolder holder) {
long time = System.currentTimeMillis();
long d = time - lastRemoval;
if (d < 100) {
removeCount++;
} else {
removeCount = 0;
}
lastRemoval = time;
ViewCompat.animate(holder.itemView)
.scaleX(0)
.scaleY(0)
.setDuration(getRemoveDuration())
.setInterpolator(mInterpolator)
.setListener(new DefaultRemoveVpaListener(holder))
.setStartDelay(removeCount * 100)
.start();
}
#Override protected void preAnimateAddImpl(RecyclerView.ViewHolder holder) {
ViewCompat.setPivotX(holder.itemView, 0);
ViewCompat.setScaleX(holder.itemView, 0);
ViewCompat.setScaleY(holder.itemView, 0);
}
#Override protected void animateAddImpl(final RecyclerView.ViewHolder holder) {
ViewCompat.animate(holder.itemView)
.scaleX(1)
.scaleY(1)
.setDuration(getAddDuration())
.setInterpolator(mInterpolator)
.setListener(new DefaultAddVpaListener(holder))
.setStartDelay(getAddDelay(holder))
.start();
}
}
This is how I have done without using any libraries - by inserting delays in the loop to remove items & restore (if needed)
clearItemsView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final List<LineItem> lineItemsCopy = new ArrayList<>(lineItems);
new Thread(new Runnable() {
#Override
public void run() {
for (int i=0; i<lineItemsCopy.size(); i++) {
runOnUiThread(new Runnable() {
#Override
public void run() {
salesOrderItemListAdapter.removeItem(0);
}
});
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
Snackbar snackbar = Snackbar.make(coordinatorLayout, getString(R.string.items_cleared_message), Snackbar.LENGTH_LONG)
.setAction(getString(R.string.label_undo), new View.OnClickListener() {
#Override
public void onClick(View v) {
new Thread(new Runnable() {
#Override
public void run() {
for (int i=0; i<lineItemsCopy.size(); i++) {
final int finalI = i;
runOnUiThread(new Runnable() {
#Override
public void run() {
salesOrderItemListAdapter.restoreItem(lineItemsCopy.get(finalI), 0);
}
});
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
}).setActionTextColor(Color.YELLOW);
snackbar.show();
}
});

Remove GridView items one by one

I want to remove items from a gridView one by one. the problem is that are all removed once !
This is my code
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
boolean sw = false;
while(!sw)
{
int i=0;
if(!adapter.isEmpty())
{
adapter.removeItem(i);
i+=1;
} else sw = true;
}
}
}, 700);
in adapter I've created a remove function.. This it is
public void removeItem(final int position)
{
data.remove(position);
notifyDataSetChanged();
}
Advices ?
The problem is you are running all the remove in one go, try with this
public void removeAllItem()
{
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run()
{
if(!adapter.isEmpty())
{
adapter.removeLastItem();
removeAllItem();
}
}
}, 700);
}
and removeLastItem() is
public void removeLastItem()
{
int lastIndex = data.size() - 1;
data.remove(lastIndex);
notifyDataSetChanged();
}
Which will remove every item from the last index every 700 miliseconds.
Declare object in class level
boolean sw = false;
Change code like below
while (!sw) {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
int i = 0;
if (!adapter.isEmpty()) {
adapter.removeItem(i);
i += 1;
} else sw = true;
}
}, 700);
}
Hope it will help you !!

Custom Adapter Listview Android

I hit my head against the wall, trying to solve this problem for some time. I'm not an experienced Android guy, so its solution might be really simple. That being said, I have the following code:
#Override
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.adminusers);
super.onCreate(savedInstanceState);
// set user_type for Viewall
mUserType = 0;
lv_adminusersListContent.addFooterView(footerView);
mUsersAdapter = new AdminUsersAdapter(mUsersList, AdminUsers.this);
lv_adminusersListContent.setAdapter(mUsersAdapter);
getUsersList();
}
private void getUsersList() {
if (UsefulFcts.isOnline(AdminUsers.this)) {
if (mThread != null && mThread.isAlive()) {
mThread.interrupt();
}
mThread = new Thread() {
#Override
public void run() {
mHandler.post(new Runnable() {
#Override
public void run() {
pDialog = new ProgressDialog(AdminUsers.this);
pDialog.setMessage("Loading.. Please wait!");
pDialog.setCancelable(false);
pDialog.show();
}
});
mUsersList.clear();
mUsersList.addAll(mServiceManager.getUsersList(mUserType,
0 + "", AdminServiceManager.sHowManyToLoad));
mArrayLength = mUsersList.size();
Log.d("arrayLength", String.valueOf(mArrayLength));
Log.d("total_results",
String.valueOf(ParserJSON.total_results));
mHandler.post(new Runnable() {
#Override
public void run() {
// refresh listview
mUsersAdapter.notifyDataSetChanged();
if (mArrayLength < ParserJSON.total_results) {
lv_adminusersListContent
.addFooterView(footerView);
} else if (mArrayLength >= ParserJSON.total_results) {
lv_adminusersListContent
.removeFooterView(footerView);
}
if (0 == mArrayLength) {
Toast.makeText(AdminUsers.this,
"No username found!",
Toast.LENGTH_SHORT).show();
}
pDialog.dismiss();
}
});
}
};
mThread.start();
} else {
Toast.makeText(AdminUsers.this, "Internet connection required!",
Toast.LENGTH_LONG).show();
}
}
#Override
protected void linkUI() {
// begin load_more view
footerView = AdminUsers.this.getLayoutInflater().inflate(
R.layout.loadmore, null);
btn_loadmore = (Button) footerView.findViewById(R.id.btn_loadmore);
// end load_more view
btn_adminusersViewall = (Button) findViewById(R.id.btn_adminusersViewall);
btn_adminusersAdmins = (Button) findViewById(R.id.btn_adminusersAdmins);
btn_adminusersClients = (Button) findViewById(R.id.btn_adminusersClients);
btn_adminusersDevs = (Button) findViewById(R.id.btn_adminusersDevs);
btn_adminAdd = (ImageButton) findViewById(R.id.btn_adminAdd);
lv_adminusersListContent = (ListView) findViewById(R.id.lv_adminusersListContent);
}
#Override
protected void setAction() {
// begin Buttons UnderHeader
btn_adminusersViewall.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
UsefulFcts.setButtonClicked(btn_adminusersViewall,
btn_adminusersClients, btn_adminusersAdmins,
btn_adminusersDevs);
mUserType = 0;
mArrayLength = -1;
lv_adminusersListContent.removeFooterView(footerView);
getUsersList();
}
});
btn_adminusersClients.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
UsefulFcts.setButtonClicked(btn_adminusersClients,
btn_adminusersDevs, btn_adminusersAdmins,
btn_adminusersViewall);
mUserType = 1;
mArrayLength = -1;
// view.setVisibility(View.GONE);
getUsersList();
}
});
btn_adminusersDevs.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
UsefulFcts.setButtonClicked(btn_adminusersDevs,
btn_adminusersClients, btn_adminusersAdmins,
btn_adminusersViewall);
mUserType = 2;
mArrayLength = -1;
lv_adminusersListContent.removeFooterView(footerView);
getUsersList();
}
});
btn_adminusersAdmins.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mUserType = 3;
mArrayLength = -1;
lv_adminusersListContent.removeFooterView(footerView);
getUsersList();
}
});
// end Buttons UnderHeader
btn_loadmore.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mThread2 = new Thread() {
#Override
public void run() {
mHandler.post(new Runnable() {
#Override
public void run() {
progressBar = new ProgressDialog(
AdminUsers.this);
progressBar
.setMessage("Loading more projects.. ");
progressBar.setCancelable(true);
progressBar.show();
}
});
mUsersList.addAll(mServiceManager.getUsersList(
mUserType, String.valueOf(mArrayLength),
AdminServiceManager.sHowManyToLoad));
mArrayLength = mUsersList.size();
mHandler.post(new Runnable() {
#Override
public void run() {
mUsersAdapter.notifyDataSetChanged();
if (mArrayLength >= ParserJSON.total_results) {
lv_adminusersListContent.removeFooterView(footerView);
}
progressBar.dismiss();
}
});
};
};
mThread2.start();
}
});
Note: I basically have a listview which content is requested from a server depending on which button (looking like a tab) I'm pressing (mUserType = 0/1/2/3). I also use a Load More button (footerView = simple layout with a button).
Everything seems to work just fine, but after "playing" with the buttons a few times (random number!) it crashes, with the following exception thrown:
02-21 11:00:49.252: E/AndroidRuntime(11728): java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread. [in ListView(2131296461, class android.widget.ListView) with Adapter(class android.widget.HeaderViewListAdapter)]
So, I looked back at the code, but couldn't see any "not on UI thread" listview notification.
1. What could the problem be?
2. Is it necessary to use 2 threads (mThread and mThread2), or could I use the same one, as one's work should start when the other ends (or isn't it ?) and should I declare them static or not ?
Also pointing me to any "Good practices" tricks I could use in the future, or "Wrong practices" that I did would be much appreciated!
PS. linkUI() and setAction() are called in super().onCreate().
The error message seems understandable : you are modifying the adapter from mThread:
mUsersList.clear();
mUsersList.addAll(mServiceManager.getUsersList(mUserType,
0 + "", AdminServiceManager.sHowManyToLoad));
You can try something like this:
final List newUserList = mServiceManager.getUsersList(mUserType,
0 + "", AdminServiceManager.sHowManyToLoad);
mArrayLength = newUserList.size();
Log.d("arrayLength", String.valueOf(mArrayLength));
Log.d("total_results",
String.valueOf(ParserJSON.total_results));
mHandler.post(new Runnable() {
#Override
public void run() {
mUsersList.clear();
mUsersList.addAll(newUserList);
// refresh listview
mUsersAdapter.notifyDataSetChanged();

ProgressDialog in Android not appearing (incorrect thread handling?)

I am trying to implement a radio player (using shoutcast streams) for android. What I want to do is, while the radio stream loads in the player, the UI displays a spinning wheel animation. On successful loading (as soon as the song starts playing) the animation disappears.
Here is the code that I am using.
PlayStopStreamingButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Thread initializer = new Thread(new Runnable() {
#Override
public void run() {
Looper.myLooper();
Looper.prepare();
progressDialog = ProgressDialog.show(RadioPlayerActivity.this, "", "Selecting Radio Station",
true);
JukefoxApplication.getHandler().post(new Runnable() {
#Override
public void run() {
radioPlayerEventListener.onPlayStopStreamingButtonClicked();
progressDialog.dismiss();
}
});
}
});
initializer.start();
}
});
I don't get any spinning animation. I am almost certain that my mistake lies in incorrect handling of threads. If someone could out the correct way, I would be grateful.
EDIT, this seems to work:
PlayStopStreamingButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
progressDialog = ProgressDialog.show(RadioPlayerActivity.this, "", "Selecting Radio Station", true);
Thread initializer = new Thread(new Runnable() {
#Override
public void run() {
radioPlayerEventListener.onPlayStopStreamingButtonClicked();
progressDialog.dismiss();
}
});
initializer.start();
}
});
You need to show progress dialog on UI thread, see below:
PlayStopStreamingButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Thread initializer = new Thread(new Runnable() {
#Override
public void run() {
Looper.myLooper();
Looper.prepare();
RadioPlayerActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
progressDialog = ProgressDialog.show(RadioPlayerActivity.this,
"", "Selecting Radio Station", true);
}
});
JukefoxApplication.getHandler().post(new Runnable() {
#Override
public void run() {
radioPlayerEventListener.onPlayStopStreamingButtonClicked();
RadioPlayerActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
progressDialog.dismiss();
}
});
}
});
initializer.start();
}
});

Categories

Resources