Using options in ActionSheet to change Button text - android

I am trying to develop an UI actionsheet in android. Using dependency:
compile 'com.baoyz.actionsheet:library:1.1.6'
I have developed an actionsheet in android which look like this:
ActionSheet in Android
I am trying to change the button text whenever any option is selected from the actionSheet. The index in the javafile below contains the string position just like array but i am unable to get the string value from that index.
Here is my javafile:
public class billBookInfo extends AppCompatActivity implements ActionSheet.ActionSheetListener{
private Button change;
private String setValue;
private Button vtype;
private Button zone;
Button next;
Button previous;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bill_book_info);
getSupportActionBar().hide();
vtype = (Button) findViewById(R.id.info_billbook_bt_vtype);
zone = (Button)findViewById(R.id.info_billbook_bt_zone);
}
}
public void onClick(View v){
switch (v.getId()) {
case R.id.info_billbook_bt_vtype:
setTheme(R.style.ActionSheetStyleiOS7);
change = vtype;
showActionSheet1();
break;
case R.id.info_billbook_bt_zone:
setTheme(R.style.ActionSheetStyleiOS7);
showActionSheet2();
change = zone;
break;
}
}
private void showActionSheet1() {
ActionSheet.createBuilder(this,getSupportFragmentManager())
.setCancelButtonTitle("Cancel")
.setOtherButtonTitles("Motorcycle","Scooter","Car","Van")
.setCancelableOnTouchOutside(true).setListener(this).show();
}
private void showActionSheet2() {
ActionSheet.createBuilder(this,getSupportFragmentManager())
.setCancelButtonTitle("Cancel")
.setOtherButtonTitles("Me", "Ko", "Sa", "Ja")
.setCancelableOnTouchOutside(true).setListener(this).show();
}
#Override
public void onDismiss(ActionSheet actionSheet, boolean isCancel) {
}
#Override
public void onOtherButtonClick(ActionSheet actionSheet, int index) {
int i = 0;
if ( i == index){
setValue = "".concat(getString(index));
change.setText(setValue);
}
}
}

Why don't you use a variable to store those values.
String vArr[] = new String[]{"Motorcycle","Scooter","Car","Van"};
String dArr[] = new String[]{"Me", "Ko", "Sa", "Ja"};
ActionSheet vSheet, dSheet;
private void showActionSheet1() {
vSheet = ActionSheet.createBuilder(this,getSupportFragmentManager())
.setCancelButtonTitle("Cancel")
.setOtherButtonTitles(vArr[0],vArr[1],vArr[2],vArr[3])
.setCancelableOnTouchOutside(true).setListener(this).show();
}
private void showActionSheet2() {
dSheet = ActionSheet.createBuilder(this,getSupportFragmentManager())
.setCancelButtonTitle("Cancel")
.setOtherButtonTitles(dArr[0],dArr[1],dArr[2],dArr[3])
.setCancelableOnTouchOutside(true).setListener(this).show();
}
#Override
public void onDismiss(ActionSheet actionSheet, boolean isCancel) {
}
#Override
public void onOtherButtonClick(ActionSheet actionSheet, int index) {
if ( actionSheet == vSheet){
change.setText(vArr[index]);
}
else{
change.setText(dArr[index]);
}
}

Related

Android RecyclerView does not refresh after insert

I have a problem with my RecyclerView.
I have a ProductDetailActivity which shows the detail of a product and i have a RecyclerView with its adapter in it.
The user can click on the give rating button which navigates to the RatingActivity where you can give a rating to the product.
The problem is that when i submit my rating and automatically go back to my RatingActivity, the RecyclerView does not get the recently added rating. i have to go back to my productlist and reclick on the product to see the recently added rating.
Here is my code:
ProductDetailActivity:
public class ProductDetailActivity extends AppCompatActivity {
public AppDatabase appDatabase;
private static final String DATABASE_NAME = "Database_Shop";
private RecyclerView mRecycleviewRating;
private RatingAdapter mAdapterRating;
private Button btnGoToRatingActivity;
List<Rating> ratings;
Product p;
int id;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_product_detail);
appDatabase = Room.databaseBuilder(getApplicationContext(),AppDatabase.class,DATABASE_NAME)
.allowMainThreadQueries()
.fallbackToDestructiveMigration()
.build();
btnGoToRatingActivity = findViewById(R.id.btn_goToRatingActivity);
Intent intent = getIntent();
id = intent.getIntExtra("productid", -1);
// pour montrer tous les ratings d'un produit, tu fais un getall
p = appDatabase.productDAO().getProductById(id);
ImageView imageView = findViewById(R.id.imageDetail);
TextView textViewName = findViewById(R.id.txt_nameDetail);
TextView textViewAuthor = findViewById(R.id.txt_authorDetail);
TextView textViewCategory = findViewById(R.id.txt_categoryDetail);
TextView textViewDetail = findViewById(R.id.txt_descriptionDetail);
Picasso.get().load(p.getProductImage()).fit().centerInside().into(imageView);
textViewName.setText(p.getProductName());
textViewAuthor.setText(p.getProductAuthor());
textViewCategory.setText(p.getProductCategory());
textViewDetail.setText(p.getProductDescription());
ratings = appDatabase.ratingDAO().getRatingByProductId(id);
mRecycleviewRating = findViewById(R.id.recyclerRating_view);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
mRecycleviewRating.setLayoutManager(linearLayoutManager);
//recyclerView.setLayoutManager(new LinearLayoutManager(this));
mAdapterRating = new RatingAdapter(ratings);
mRecycleviewRating.setAdapter(mAdapterRating);
btnGoToRatingActivity.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(ProductDetailActivity.this, RatingActivity.class);
i.putExtra("productid", p.getProduct_id());
startActivity(i);
}
});
mAdapterRating.notifyDataSetChanged();
}
#Override
public void onResume() {
super.onResume();
ratings = appDatabase.ratingDAO().getRatingByProductId(id); // reload the items from database
mAdapterRating.notifyDataSetChanged();
System.out.println(mAdapterRating.ratings.size());
}
}
RatingActivity:
public class RatingActivity extends AppCompatActivity implements RatingGiveFragment.RatingListener {
RelativeLayout mRelativeLayout;
private Button btnConfirmRating;
private EditText mComment;
private RatingBar mRatingBar;
public AppDatabase appDatabase;
private RatingAdapter mAdapter;
List<Rating> ratings;
private static final String DATABASE_NAME = "Database_Shop";
Product p;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_rating);
appDatabase = Room.databaseBuilder(getApplicationContext(),AppDatabase.class,DATABASE_NAME)
.allowMainThreadQueries()
.fallbackToDestructiveMigration()
.build();
int idProduct = RatingActivity.this.getIntent().getIntExtra("productid",-1);
p = appDatabase.productDAO().getProductById(idProduct);
mRatingBar = findViewById(R.id.rating_bar);
mComment = findViewById(R.id.txt_insertOpinionText);
mRelativeLayout = findViewById(R.id.activity_rating);
btnConfirmRating = findViewById(R.id.buttonConfirmRating);
mAdapter = new RatingAdapter(ratings);
btnConfirmRating.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(!checkEmptyFields()) {
Rating rating = new Rating(p.getProduct_id(),UserConnected.connectedUser.getUser_id(),mRatingBar.getRating(), UserConnected.connectedUser.getUsername(), mComment.getText().toString());
appDatabase.ratingDAO().insertRating(rating);
mAdapter.notifyDataSetChanged();
finish();
}else{
Toast.makeText(RatingActivity.this, "Empty Fields", Toast.LENGTH_SHORT).show();
}
}
});
}
/*private class insertRating extends AsyncTask<String,Integer, Integer>
{
#Override
protected Integer doInBackground(String... strings) {
Rating rating = new Rating(Integer.parseInt(strings[0]), Integer.parseInt(strings[1]), Integer.parseInt(strings[2]), strings[3], strings[4]);
appDatabase.ratingDAO().insertRating(rating);
return 1;
}
#Override
protected void onPostExecute(Integer integer) {
super.onPostExecute(integer);
if (integer == 1)
{
Toast.makeText(getApplicationContext(), getString(R.string.createRating), Toast.LENGTH_SHORT).show();
}
}
}*/
#Override
public void ratingChanged(int newRating) {
RatingTextFragment textFragment = (RatingTextFragment) getSupportFragmentManager().findFragmentById(R.id.fmt_text);
textFragment.setRating(newRating);
}
private boolean checkEmptyFields(){
if(TextUtils.isEmpty(mComment.getText().toString())){
return true;
}else{
return false;
}
}
}
RatingAdapter:
public class RatingAdapter extends RecyclerView.Adapter<RatingAdapter.RatingViewHolder> {
List<Rating> ratings;
public RatingAdapter(List<Rating> ratings){
this.ratings = ratings;
}
#NonNull
#Override
public RatingViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.rating_row,viewGroup, false);
return new RatingViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull RatingViewHolder ratingViewHolder, int position) {
ratingViewHolder.ratingUsername.setText(ratings.get(position).getRatingUsername());
ratingViewHolder.ratingNumber.setText(String.valueOf(ratings.get(position).getRatingNumber()) + "/5");
ratingViewHolder.ratingComment.setText(ratings.get(position).getRatingText());
}
#Override
public int getItemCount() {
return ratings.size();
}
public static class RatingViewHolder extends RecyclerView.ViewHolder{
public TextView ratingUsername;
public TextView ratingNumber;
public TextView ratingComment;
public RatingViewHolder(#NonNull View itemView) {
super(itemView);
ratingUsername = itemView.findViewById(R.id.txt_usernamerating);
ratingNumber = itemView.findViewById(R.id.num_rating);
ratingComment = itemView.findViewById(R.id.txt_ratingComment);
}
}
}
Pictures:
You get no update in the ProductDetailActivity because you are not updating the data object ratings in the ProductDetailActivity that is the basis for the RatingAdapter.
It would be better to use startActivityForResult in the onClick()method of the ProductDetailActivity. Then you need to override the onActivityResult() method in the ProductDetailActivity. Evaluate the return values and update your data source if necessary, then call notifyDataSetChanged.
This is just pseudo code!
Changes to ProductDetailActivity:
btnGoToRatingActivity.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(ProductDetailActivity.this, RatingActivity.class);
i.putExtra("productid", p.getProduct_id());
// with this you are telling the activity to expect results and..
//..to deal with them in onActivityResult
startActivityForResult(i, 1);
}
});
// You do not need this next line because setting the adaper triggers the first
//mAdapterRating.notifyDataSetChanged();
}
Add the onActivityResult() method to the ProductDetailActivity.
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1) {
if(resultCode == Activity.RESULT_OK){
// trigger a method to update the data object that is linked to the adapter
ratings = appDatabase.ratingDAO().getRatingByProductId(id);
// and now that the data has actually been updated you can call notifyDataSetChanged!!
mAdapterRating.notifyDataSetChanged();
}
if (resultCode == Activity.RESULT_CANCELED) {
//Probably do nothing or make a Toast "Canceled"??
}
}
}
Changes to RatingActivity:
btnConfirmRating.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(!checkEmptyFields()) {
// I will just assume this works!
Rating rating = new Rating(p.getProduct_id(),UserConnected.connectedUser.getUser_id(),mRatingBar.getRating(), UserConnected.connectedUser.getUsername(), mComment.getText().toString());
appDatabase.ratingDAO().insertRating(rating);
Intent intent = new Intent();
//If you need to return some value.. do it here other you do not need it
//intent.putExtra("result", result);
setResult(Activity.RESULT_OK, intent);
finish();
}else{
Toast.makeText(RatingActivity.this, "Empty Fields", Toast.LENGTH_SHORT).show();
}
}
});
Please be aware in RatingActivity that in btnConfirmRating.setOnClickListener notifying the adapter with mAdapter.notifyDataSetChanged(); does nothing: firstly, because the adapter in the RatingActivity has nothing to do with the adapter in the ProductDetailActivity; secondly: you call finish(); in the next line of code.

How to set up a custom listener in a custom dialog for android?

I'm currently having trouble setting up my custom listener. I just want to pass a string from my dialog to my fragment (where I set up the dialog). I was trying to follow this tutorial: https://www.youtube.com/watch?v=ARezg1D9Zd0.
At minute 10:38, he sets up the listener.
This only problem is that in this, he uses DialogFragment, but I'm extending dialog and I don't know how to attach the context to the listener.
I've tried to set it up in onAttachedToWindow() and in the dialog constructor but it crashes.
What should I actually do?
I'd also appreciate it if someone could explain what the difference is between:
onAttachedToWindow() vs. onAttach(Context context).
Thanks!
MY CUSTOM DIALOG BOX:
public class NewListDialog extends Dialog implements View.OnClickListener {
private Activity c;
private TextInputLayout textInputLayout;
private TextInputEditText editText;
private LinearLayout dialog_root_view;
private Animation fade_out;
private String list_name;
private NewListDialogListener listener;
NewListDialog(Activity a) {
super(a);
this.c = a;
//ANOTHER ATTEMPT TO ATTACH CONTEXT TO LISTENER
//listener = (NewListDialogListener) a.getApplicationContext();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.new_list_dialog);
MaterialButton cancel = findViewById(R.id.dialog_new_list_cancel_button);
MaterialButton create = findViewById(R.id.dialog_new_list_create_button);
textInputLayout = findViewById(R.id.dialog_text_input_layout);
editText = findViewById(R.id.dialog_edit_text);
dialog_root_view = findViewById(R.id.dialog_root);
fade_out = AnimationUtils.loadAnimation(c, R.anim.fade_out_dialog);
editText.setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View view, int i, KeyEvent keyEvent) {
if (isTextValid(editText.getText())) {
textInputLayout.setError(null);
return true;
}
return false;
}
});
cancel.setOnClickListener(this);
create.setOnClickListener(this);
}
#Override
public void onClick(View view) {
switch (view.getId()) {
//Cancel Button
case R.id.dialog_new_list_cancel_button:
dialog_root_view.startAnimation(fade_out);
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
dismiss();
}
}, 200);
break;
//Create Button
case R.id.dialog_new_list_create_button:
if (!isTextValid(editText.getText())) {
textInputLayout.setError(c.getString(R.string.dialog_error));
} else {
textInputLayout.setError(null);
//record input string
list_name = editText.getText().toString();
//send information to parent activity
//What to put here?
listener.createListName(list_name);
dismiss();
}
break;
default:
break;
}
}
private boolean isTextValid(#Nullable Editable text) {
return text != null && text.length() > 0;
}
//ATTEMPT TO ATTACH CONTEXT TO LISTENER
#Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
try {
listener = (NewListDialogListener) c.getBaseContext();
} catch (ClassCastException e) {
throw new ClassCastException(c.getBaseContext().toString() + "must implement ExampleDialogListener");
}
}
public interface NewListDialogListener {
void createListName(String listname);
}
}
In case you define a custom dialog then you can declare a method to allow other components call it or listen events on this dialog. Add this method to you custom dialog.
public void setNewListDialogListener(NewListDialogListener listener){
this.listener = listener;
}
NewListDialog.java
public class NewListDialog extends Dialog implements View.OnClickListener {
private Activity c;
private TextInputLayout textInputLayout;
private TextInputEditText editText;
private LinearLayout dialog_root_view;
private Animation fade_out;
private String list_name;
private NewListDialogListener listener;
NewListDialog(Activity a) {
super(a);
this.c = a;
}
public void setNewListDialogListener(NewListDialogListener listener) {
this.listener = listener;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.new_list_dialog);
MaterialButton cancel = findViewById(R.id.dialog_new_list_cancel_button);
MaterialButton create = findViewById(R.id.dialog_new_list_create_button);
textInputLayout = findViewById(R.id.dialog_text_input_layout);
editText = findViewById(R.id.dialog_edit_text);
dialog_root_view = findViewById(R.id.dialog_root);
fade_out = AnimationUtils.loadAnimation(c, R.anim.fade_out_dialog);
editText.setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View view, int i, KeyEvent keyEvent) {
if (isTextValid(editText.getText())) {
textInputLayout.setError(null);
return true;
}
return false;
}
});
cancel.setOnClickListener(this);
create.setOnClickListener(this);
}
#Override
public void onClick(View view) {
switch (view.getId()) {
//Cancel Button
case R.id.dialog_new_list_cancel_button:
dialog_root_view.startAnimation(fade_out);
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
dismiss();
}
}, 200);
break;
//Create Button
case R.id.dialog_new_list_create_button:
if (!isTextValid(editText.getText())) {
textInputLayout.setError(c.getString(R.string.dialog_error));
} else {
textInputLayout.setError(null);
//record input string
list_name = editText.getText().toString();
//send information to parent activity
//What to put here?
if (listener != null) {
listener.createListName(list_name);
}
dismiss();
}
break;
default:
break;
}
}
private boolean isTextValid(#Nullable Editable text) {
return text != null && text.length() > 0;
}
public interface NewListDialogListener {
void createListName(String listname);
}
}
In other components such as an activity which must implements NewListDialogListener.
NewListDialog dialog = new NewListDialog(this);
dialog.setNewListDialogListener(this);
If you don't want the activity implements NewListDialogListener then you can pass a listener instead.
NewListDialog dialog = new NewListDialog(this);
dialog.setNewListDialogListener(new NewListDialog.NewListDialogListener() {
#Override
public void createListName(String listname) {
// TODO: Your code here
}
});
In android Fragments and Activity has lifecycles. Fragments are hosted inside Activity and get the context of host activity via onattach method.
On the other hand Dialog is extended from Object (God class) without any lifecycle and should be treaded as an object.
If your activity is implementing NewListDialogListener then you can do
listener = (NewListDialogListener) a;
onAttachedToWindow : mean the dialog will be drawn on screen soon
and
getApplicationContext() will give you the context object of the application (one per app) which is surely not related with your listener and hence won't work
Reference :
Android DialogFragment vs Dialog
Difference between getContext() , getApplicationContext() , getBaseContext() and “this”
You can use RxAndroid instead of using listener, in this situation I use RxAndroid to get data from dialogs to activities or fragments.
Just need to create a PublishSubject and get the observed data. on activity or fragment :
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
PublishSubject<String > objectPublishSubject = PublishSubject.create();
objectPublishSubject.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.newThread())
.subscribe(this::onNext);
CustomDialog customDialog = new CustomDialog(this, objectPublishSubject);
customDialog.show();
}
private void onNext(String data) {
Log.i("DIALOG_DATA", data);
}
and you can create dialog like this :
public class CustomDialog extends Dialog implements View.OnClickListener {
private PublishSubject<String> subject;
public CustomDialog(#NonNull Context context, PublishSubject<String> subject) {
super(context);
this.subject = subject;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.custom_dialog);
findViewById(R.id.button).setOnClickListener(this);
}
#Override
public void onClick(View v) {
subject.onNext("Data");
dismiss();
}

How to validate a input field and prevent Dialog dismissing

In my application I extend the Dialog class to get user input for each field and now I want to validate them.
public abstract class EditDialogHelper extends Dialog implements android.view.View.OnClickListener {
private Context context;
private String title;
private String field;
private String positive;
private String negative;
private EditText etField;
private TextView tvCount;
private int characterCount;
public EditDialogHelper(Context context, String title, String field, String positive, String negative, int characterCount) {
super(context);
this.context = context;
this.title = title;
this.field = field;
this.positive = positive;
this.negative = negative;
this.characterCount = characterCount;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.dialog_edit_view);
TextView tvTitle = (TextView) findViewById(R.id.tvTitle);
etField = (EditText) findViewById(R.id.etField);
tvCount = (TextView) findViewById(R.id.tvInputCount);
Button btnConfirmationOk = (Button) findViewById(R.id.btnPositive);
Button btnConfirmationCancel = (Button) findViewById(R.id.btnNegative);
final TextWatcher textWatcher = new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
tvCount.setText(String.valueOf(characterCount - s.length()));
}
#Override
public void afterTextChanged(Editable s) {
}
};
etField.addTextChangedListener(textWatcher);
tvTitle.setText(title);
etField.setText(field);
etField.setFilters(new InputFilter[]{new InputFilter.LengthFilter(characterCount)});
btnConfirmationOk.setOnClickListener(this);
btnConfirmationCancel.setOnClickListener(this);
}
public String getValue() {
return etField.getText().toString().trim();
}
private boolean validateInputs(String value) {
boolean valid = false;
if (value != null && !(value.equals(""))) {
valid = true;
} else {
etField.setError("This can't be left empty");
}
return valid;
}
}
Once the dialog opens up I want it to be validated once the btnConfirmationOk is clicked and if the field is empty, it should be prevented from dismissing the dialog while showing the error.
Where should I use this validateInputs method and in which way it should be modified.
Answer is quite simple i guess
#Override
void onClick(View view) {
if (view.getId == R.id.btnPositive) {
boolean valid = validate("my string");
if(valid) {
// do stuff
dissmis();
}
} else {
dissmis();
}
}
But in my oppinion you should set different listeners to your possitive and negative buttons, instead of tracking everything with EditDialogHelper class.
this could be done like this.
button.setOnClickListener(new OnClickListener {
#Override
void onClick(View v) {
}
});
p.s. I wrote everything from my head so this could contain compilation errors.

I can not create buttons for possible answers android studio

I have an issue with a small project in android studio where on animal drawings guess things etc. But guess I have to write the name to accept a button and image lights up and goes to the next , what I want you to show me an answer with buttons say 3 button 1 is the correct answer and the other two false I took a long time with this and even I can not do it if I would appreciate any help
Here the code of the class where the shadows and images run
public class Categoria extends Activity {
public static String[] nombre_cosa={"cerdo","ave","caballo","conejo","elefante","gallina","gato",
"rana","perro","pato","oveja","leon","jirafa",
"raton","vaca","autobus","automovil","avion","bicicleta","camioneta",
"casa","celular","guitarra","motocicleta","silla","television","durazno","fresa","mango",
"uvas","sandia","platano","coco","pera","naranja","manzana",
"bart","batman","cerebro","chavo","goku","homero","marge",
"patricio","pepa","phineas","quico","spiderman","thor","superman"};
public static String[] sombra_cosa={"s_cerdo","s_ave","s_caballo","s_conejo","s_elefante","s_gallina","s_gato",
"s_rana","s_perro","s_pato","s_oveja","s_leon","s_jirafa",
"s_raton","s_vaca","s_autobus","s_automovil","s_avion","s_bicicleta","s_camioneta",
"s_casa","s_celular","s_guitarra","s_motocicleta","s_silla","s_television","s_durazno","s_fresa","s_mango",
"s_uvas","s_sandia","s_platano","s_coco","s_pera","s_naranja","s_manzana",
"s_bart","s_batman","s_cerebro","s_chavo","s_goku","s_homero","s_marge",
"s_patricio","s_pepa","s_phineas","s_quico","s_spiderman","s_thor","s_superman"};
public static boolean[] estado={false,false,false,false,false,false,
false,false,false,false,false,false,
false,false,false,false,false,false,false,
false,false,false,false,false,false,false,false,
false,false,false,false,false,false,false,
false,false,false,false,false,false,false,false,false,false,
false,false,false,false,false,false};
public static int cosas_adivinadas=0;
private int intentos=3;
private Button aceptar;
private TextView mensaje_intentos,mensaje_cuenta;
private EditText usuario_cosa;
private int numero_generado=0;
private ImageView miimagen;
private MediaPlayer reproductor;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
setContentView(R.layout.activity_categoria);
aceptar=(Button) findViewById(R.id.btnaceptar);
mensaje_intentos=(TextView) findViewById(R.id.lblintentos);
mensaje_cuenta=(TextView) findViewById(R.id.lblcuenta);
usuario_cosa=(EditText) findViewById(R.id.txtcosa);
miimagen=(ImageView) findViewById(R.id.imgcosa);
CargarPreferencias();
new MiTarea().execute();
reproductor= MediaPlayer.create(this,R.raw.yansha);
reproductor.setLooping(true);
reproductor.start();
mensaje_intentos.setText("Tiene " + intentos + " intentos");
aceptar.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String nombre=usuario_cosa.getText().toString().toLowerCase();
if(nombre.equals(nombre_cosa[numero_generado]))
{
establecer_cosa(numero_generado);
estado[numero_generado]=true;
cosas_adivinadas++;
esperar();
}
else
{
Toast.makeText(getApplicationContext(), "Incorrecto", Toast.LENGTH_SHORT).show();
intentos=intentos-1;
mensaje_intentos.setText("Tiene " + intentos + " intentos");
}
if (intentos==0)
{
removerPreferencias();
Intent i = new Intent(Categoria.this,Perder.class);
startActivity(i);
finish();
}
}
});
}
#Override
protected void onResume() {
super.onResume();
reproductor.start();
}
public void esperar()
{
new CountDownTimer(5000,1000)
{
#Override
public void onTick(long millisUntilFinished) {
mensaje_cuenta.setText("Generando en " + (millisUntilFinished/1000));
}
#Override
public void onFinish() {
if (cosas_adivinadas==nombre_cosa.length)
{
finish();
}
else
{
new MiTarea().execute();
mensaje_cuenta.setText("");
usuario_cosa.setText("");
}
}
}.start();
}
public void CargarPreferencias()
{
SharedPreferences mispreferencias = getSharedPreferences("PreferenciaCosa", Context.MODE_PRIVATE);
intentos=mispreferencias.getInt("intentos",3);
cosas_adivinadas=mispreferencias.getInt("adivinados",0);
for (int i=0;i<nombre_cosa.length;i++)
{
estado[i]=mispreferencias.getBoolean(nombre_cosa[i],false);
}
}
public void GuardarPreferencias()
{
SharedPreferences mispreferencias = getSharedPreferences("PreferenciaCosa", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = mispreferencias.edit();
editor.putInt("intentos",intentos);
editor.putInt("adivinados",cosas_adivinadas);
for (int i=0;i<nombre_cosa.length;i++)
{
editor.putBoolean(nombre_cosa[i], estado[i]);
}
editor.commit();
}
private void establecer_cosa(int numero)
{
int resId = getResources().getIdentifier(nombre_cosa[numero], "drawable", getPackageName());
miimagen.setImageResource(resId);
}
private void establecer_sombra(int numero)
{
int resId = getResources().getIdentifier(sombra_cosa[numero], "drawable", getPackageName());
miimagen.setImageResource(resId);
}
private void removerPreferencias()
{
SharedPreferences settings = getSharedPreferences("PreferenciaCosa", Context.MODE_PRIVATE);
settings.edit().clear().commit();
}
#Override
protected void onStop() {
if (intentos==0)
{
removerPreferencias();
}
else
{
GuardarPreferencias();
}
reproductor.pause();
super.onStop();
}
#Override
protected void onDestroy() {
if (reproductor.isPlaying())
{
reproductor.stop();
reproductor.release();
}
super.onDestroy();
}
private class MiTarea extends AsyncTask<Void, Void, Void> {
private int valor_generado;
#Override
protected Void doInBackground(Void... params) {
do {
valor_generado=((int)(Math.random()*nombre_cosa.length));
}while(estado[valor_generado]);
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
numero_generado = valor_generado;
establecer_sombra(valor_generado);
super.onPostExecute(aVoid);
}
}
}
Create a variable like this:
boolean isTextCorrect = false;
In default, the button is invisible.
Implement a listener. If the text in the textfield changed and its correct switch isTextCorrect to true and make the button visible (clickable).
if(isTextCorrect){
button.setVisible(View.VISIBLE);
}

The value of the variable has been suddenly set to 0

I'm doing an activity to measure how long it takes a person to do an exercise, but it has a bug that I couldn't resolve yet...
The TrainingFragment shows a list of exercises that the user can click and then my ExerciseActivity is launched and runs until the variable "remainingsSets" is setted to 0.
When I click in the first time at any exercise, everything works fine, the ExerciseActivity works correctly end return to the TrainingFragment. But then, if I try to click in another exercise, the ExerciseActivity is just closed.
In my debug, I could see that the variable "remainingSets" comes with it's right value (remainingSets = getIntent().getIntExtra("remaining_sets", 3)), but when the startButton is clicked, I don't know why the variable "remainingSets" is setted to 0 and then the activity is closed because this condition: if (remainingSets > 0){...}.
Here is my TrainingFragment:
public class TrainingFragment extends Fragment {
private final static int START_EXERCISE = 1;
private Training training;
private String lastItemClicked;
private String[] values;
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
Bundle bundle = getArguments();
if (bundle != null) {
training = bundle.getParcelable("training");
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return (ScrollView) inflater.inflate(R.layout.template_exercises, container, false);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
LinearLayout exercisesContainer = (LinearLayout) getView().findViewById(R.id.exercises);
LayoutInflater inflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
List<Exercise> exercises = training.getExercises();
values = new String[exercises.size()];
if (savedInstanceState != null) {
values = savedInstanceState.getStringArray("values");
}
for (int i = 0; i < exercises.size(); i++) {
final View exerciseView = inflater.inflate(R.layout.template_exercise, null);
exerciseView.setTag(String.valueOf(i));
TextView remainingSets = (TextView) exerciseView.findViewById(R.id.remaining_sets);
if (savedInstanceState != null) {
remainingSets.setText(values[i]);
} else {
String sets = exercises.get(i).getSets();
remainingSets.setText(sets);
values[i] = sets;
}
exerciseView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(getActivity(), ExerciseActivity.class);
intent.putExtra("remaining_sets",
Integer.valueOf(((TextView) v.findViewById(R.id.remaining_sets)).getText().toString()));
lastItemClicked = v.getTag().toString();
startActivityForResult(intent, START_EXERCISE);
}
});
exercisesContainer.addView(exerciseView);
}
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putStringArray("values", values);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
View view = ((LinearLayout) getView().findViewById(R.id.exercises)).findViewWithTag(lastItemClicked);
if (requestCode == START_EXERCISE) {
if (resultCode == Activity.RESULT_OK) { // the exercise had been
// finished.
((TextView) view.findViewById(R.id.remaining_sets)).setText("0");
view.setClickable(false);
values[Integer.valueOf(lastItemClicked)] = "0";
} else if (resultCode == Activity.RESULT_CANCELED) {
String remainingSets = data.getStringExtra("remaining_sets");
((TextView) view.findViewById(R.id.remaining_sets)).setText(remainingSets);
values[Integer.valueOf(lastItemClicked)] = remainingSets;
}
}
}
}
My ExerciseActivity:
public class ExerciseActivity extends Activity {
private Chronometer chronometer;
private TextView timer;
private Button startButton;
private Button endButton;
private int remainingSets;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_exercise);
ExerciseEvents.addExerciseListener(new PopupExerciseListener());
chronometer = (Chronometer) findViewById(R.id.exercise_doing_timer);
timer = (TextView) findViewById(R.id.timer);
startButton = (Button) findViewById(R.id.start_exercise);
startButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
ExerciseEvents.onExerciseBegin();
}
});
endButton = (Button) findViewById(R.id.end_exercise);
endButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
ExerciseEvents.onExerciseRest();
}
});
}
#Override
public void onBackPressed() {
Intent intent = new Intent();
intent.putExtra("remaining_sets", String.valueOf(remainingSets));
setResult(RESULT_CANCELED, intent);
super.onBackPressed();
}
public class PopupExerciseListener implements ExerciseListener {
public PopupExerciseListener() {
remainingSets = getIntent().getIntExtra("remaining_sets", 3);
}
#Override
public void onExerciseBegin() {
if (remainingSets > 0) {
chronometer.setVisibility(View.VISIBLE);
timer.setVisibility(View.GONE);
chronometer.setBase(SystemClock.elapsedRealtime());
chronometer.start();
startButton.setVisibility(View.GONE);
endButton.setVisibility(View.VISIBLE);
} else {
ExerciseEvents.onExerciseFinish();
}
}
#Override
public void onExerciseFinish() {
setResult(RESULT_OK);
finish();
}
#Override
public void onExerciseRest() {
chronometer.setVisibility(View.GONE);
endButton.setVisibility(View.GONE);
timer.setVisibility(View.VISIBLE);
long restTime = getIntent().getLongExtra("time_to_rest", 60) * 1000;
new CountDownTimer(restTime, 1000) {
#Override
public void onTick(long millisUntilFinished) {
timer.setText(String.valueOf(millisUntilFinished / 1000));
}
#Override
public void onFinish() {
ExerciseEvents.onExerciseBegin();
}
}.start();
remainingSets--;
}
}
}
And my ExerciseEvents:
public class ExerciseEvents {
private static LinkedList<ExerciseListener> mExerciseListeners = new LinkedList<ExerciseListener>();
public static void addExerciseListener(ExerciseListener listener) {
mExerciseListeners.add(listener);
}
public static void removeExerciseListener(String listener) {
mExerciseListeners.remove(listener);
}
public static void onExerciseBegin() {
for (ExerciseListener l : mExerciseListeners) {
l.onExerciseBegin();
}
}
public static void onExerciseRest() {
for (ExerciseListener l : mExerciseListeners) {
l.onExerciseRest();
}
}
public static void onExerciseFinish() {
for (ExerciseListener l : mExerciseListeners) {
l.onExerciseFinish();
}
}
public static interface ExerciseListener {
public void onExerciseBegin();
public void onExerciseRest();
public void onExerciseFinish();
}
}
Could anyone give me any help?
After you updated your code, I see you have a big memory leak in your code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_exercise);
ExerciseEvents.addExerciseListener(new PopupExerciseListener());
....
}
The call ExerciseEvents.addExerciseListener(new PopupExerciseListener()) adds a new PopupExerciseListener to a static/global list: ExcerciseEvents.mExerciseListeners. Since the class PopupExerciseListener is an inner-class, it implicitly holds a reference to its enclosing ExcerciseActivity. This mean your code is holding on to each instance of ExcerciseActivity forever. Not good.
This may also explain the weird behavior you see. When one of the onExcersizeXXX() methods is called, it will call all ExcerciseListeners in the linked-list, the ones from previous screens and the current one.
Try this in your ExcerciseActivity.java:
....
ExerciseListener mExerciseListener;
....
#Override
protected void onCreate(Bundle savedInstanceState) {
....
....
mExerciseListener = new PopupExerciseListener()
ExerciseEvents.addExerciseListener(mExerciseListener);
....
....
}
#Override
protected void onDestroy() {
ExerciseEvents.removeExerciseListener(mExerciseListener);
super.onDestroy();
}
....
In onDestroy, you deregister your listener, preventing a memory leak and preventing odd multiple callbacks to PopupExerciseListeners that are attached to activities that no longer exist.

Categories

Resources