Class variables in OnClickListener - android

I have a separate class for my OnClickListeners. I would like to add items to an arraylist when i click a button, and remove them when I click a 2nd time. I have the framework here:
public void onClick(View v) {
Button button = (Button)v;
if(isClicked) {
button.setText("Enabled");
Log.v("Spirit: ", v.getTag() + "");
spirits_list.add(v.getTag() + "");
isClicked = false;
} else {
button.setText("Disabled");
spirits_list.remove(v.getId()-1);
isClicked = true;
}
}
I also have an ArrayList initialized at the top, but every time I click a button it reinitializes the ArrayList. How can I get around this? Also, I need to be able to save the ArrayList to SharedPreferences - how can I do this from my OnClickListener?

Since you use your own class, you can pass all the goodness around in class members:
class MyListener implements View.OnClickListener {
private ArrayList<Object> spirits_list;
private Context ctx;
public MyListener( Context ctx, ArrayList<Object> list ) {
super();
this.ctx = ctx;
this.spirits_list = list;
}
public void onClick(View v) {
Button button = (Button)v;
if(isClicked) {
button.setText("Enabled");
Log.v("Spirit: ", v.getTag() + "");
this.spirits_list.add(v.getTag() + "");
isClicked = false;
} else {
button.setText("Disabled");
this.spirits_list.remove(v.getId()-1);
isClicked = true;
}
}
}
The context will allow you to access SharedPrefs as well. You can then invoke this bit as follows:
view.setOnClickListener( new MyListener( this, spirits_list ) );

Related

Checked the Checkboxes that is already checked

I have one EditText (edModelColor). when user click on edModelColor(EditText) then the custom dialog will be called.Custom dialog consist of RecylerView and searchview and one custom row for each item. Custom row contains ImageView(icon), TextView (colorNames) and checkbox for selection. When user click on any checkbox I passed the colorName and its position in adapter into method checkAndRemove. this method will add or remove the color name according to its adapter position and the colorNames will added into edModelColor(EditText). its working fine but the problem is that once the user click on edModelColor(EditText) again, I want to checked those checkboxes which are already checked inside CustomDialogbox.I have seen some articles online but I could not understand what they meant.
bodyColorDialog:
private void bodyColorDialog() {
TextView txtClose;
TextView tvCancel;
Button btnOk;
bodyColorDialog.setContentView(R.layout.ed_body_color_dialog);
bodyColorDialog.setCancelable(false);
txtClose = bodyColorDialog.findViewById(R.id.txtModelClose);
tvCancel = bodyColorDialog.findViewById(R.id.tvCancel);
btnOk = bodyColorDialog.findViewById(R.id.btnOk);
edBodyColorSearchView = bodyColorDialog.findViewById(R.id.edBodyColorSearchViewColor);
edBodyColorRecylerView = bodyColorDialog.findViewById(R.id.edBodyColorRecylerView);
edBodyColorRecylerView.setLayoutManager(new LinearLayoutManager(getContext()));
bodyColorArrayList.clear();
setUpBodyColorArrayList();
btnOk.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
selectionCMap = new HashMap<>();
selectionCMap = edBodyColorAdapter.selectionColorsMap;
for(String value : selectionCMap.values()){
/* tv.setText(tv.getText() + "\n" + value);*/
edBodyColor.append(value + ",");
}
bodyColorDialog.dismiss();
}
});
txtClose.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
bodyColorDialog.dismiss();
}
});
tvCancel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
bodyColorDialog.dismiss();
}
});
bodyColorDialog.show();
}
private void setUpBodyColorArrayList() {
bodyColorArrayList.clear();
String bodyColorName[] = getResources().getStringArray(R.array.body_color_array);
int bodyColorIcons[] = {R.drawable.red, R.drawable.black, R.drawable.violet, R.drawable.white,
R.drawable.orange, R.drawable.blue, R.drawable.green, R.drawable.yello};
for(int i =0; i < bodyColorIcons.length; i++)
{
bodyColorArrayList.add(new edModelBodyColor(bodyColorName[i], bodyColorIcons[i]));
}
edBodyColorAdapter = new edBodyColorAdapter(getContext(), bodyColorArrayList);
edBodyColorRecylerView.setAdapter(edBodyColorAdapter);
edBodyColorSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String queryString) {
edBodyColorAdapter.getFilter().filter(queryString);
return false;
}
#Override
public boolean onQueryTextChange(String queryString) {
edBodyColorAdapter.getFilter().filter(queryString);
return false;
}
});
}
edBodyColorAdapter.java
holder.checkBoxColor.setOnCheckedChangeListener(new
CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {
int position = holder.getAdapterPosition();
clickedColorNamePosition = edBodyColorArrayList.indexOf(filteredArrayList.get(position));
String name = edBodyColorArrayList.get(clickedColorNamePosition).getBodyColorName();
Toast.makeText(context, "name = " + name, Toast.LENGTH_SHORT).show();
//this mthod will check if selected checkbox value is already present or not.
// It present then remove ( means user unchecked box) and if value is not there means user has selected checkbox
checkAndRemove(position,name);
}
});
checkAndRemove:
private void checkAndRemove(int position, String name) {
if(selectionColorsMap.containsKey(position)){
selectionColorsMap.remove(position);
Toast.makeText(context, "removed", Toast.LENGTH_SHORT).show();
}else {
selectionColorsMap.put(position, name);
Toast.makeText(context, "added", Toast.LENGTH_SHORT).show();
}
}
preview:
Conculusion: I want to check these checkboxes values when user click again on edBodyColor dialog..
I as can see, you are initializing the ArrayList of colors every time you are showing the dialog, that's why, you start always at initial state.
Instead, you should initialized the ArrayList inside onCreate() and reuse it every time to maintain the previous state.

How do I update my static context value saved from shared preferences?

I am planning to implement an easter egg to change my API through an alertdialog, but currently after I change my url endpoint and submit it it saves it in shared preferences, but next time i save it, it does save it in shared preferences ,but doesn't reflect in the app. How do I make it such that every single time i change it ,it applies to my apiendpoint as expected:
Alertdialog which triggers on 5 taps:
myimage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
long time= System.currentTimeMillis();
//if it is the first time, or if it has been more than 3 seconds since the first tap ( so it is like a new try), we reset everything
if (startMillis==0 || (time-startMillis> 3000) ) {
startMillis=time;
count=1;
}
//it is not the first, and it has been less than 3 seconds since the first
else{ // time-startMillis< 3000
count++;
}
if (count==5) {
final AlertDialog dialogBuilder = new AlertDialog.Builder(LoginActivity.this).create();
LayoutInflater inflater = LoginActivity.this.getLayoutInflater();
View dialogView = inflater.inflate(R.layout.custom_dialog, null);
final EditText editText = (EditText) dialogView.findViewById(R.id.edt_comment);
Button submitButton = (Button) dialogView.findViewById(R.id.buttonSubmit);
Button cancelButton = (Button) dialogView.findViewById(R.id.buttonCancel);
Button resetButton = (Button) dialogView.findViewById(R.id.buttonReset);
editText.setTextColor(getResources().getColor(R.color.black,null));
if(SharedPreferencesHelper.getSomeStringValue(getApplicationContext()) != null) {
editText.setText( SharedPreferencesHelper.getSomeStringValue(getApplicationContext()));
}
cancelButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
dialogBuilder.dismiss();
}
});
submitButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//save the endpoint value in shared preferences
SharedPreferencesHelper.setSomeStringValue(getApplicationContext(),editText.getText().toString());
dialogBuilder.dismiss();
}
});
resetButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
SharedPreferencesHelper.setSomeStringValue(getApplicationContext(),BuildConfig.BASE_URL);
dialogBuilder.dismiss();
}
});
dialogBuilder.setView(dialogView);
dialogBuilder.setCanceledOnTouchOutside(false);
dialogBuilder.show();
}
}
});
Here's my sharedpreferenceshelper:
public class SharedPreferencesHelper {
private static final String APP_SETTINGS = "APP_SETTINGS";
// properties
private static final String SOME_STRING_VALUE = "SOME_STRING_VALUE";
// other properties...
private SharedPreferencesHelper() {}
private static SharedPreferences getSharedPreferences(Context context) {
return context.getSharedPreferences(APP_SETTINGS, Context.MODE_PRIVATE);
}
public static String getSomeStringValue(Context context) {
return getSharedPreferences(context).getString(SOME_STRING_VALUE , null);
}
public static void setSomeStringValue(Context context, String newValue) {
final SharedPreferences.Editor editor = getSharedPreferences(context).edit();
editor.putString(SOME_STRING_VALUE , newValue);
editor.apply();
}
}
Finally, here's my Apiendpoint class:
final class ApiEndPoint {
private static String NEW_URL = SharedPreferencesHelper.getSomeStringValue(MyApp.getAppContext());
static final String ENDPOINT_SERVER_LOGIN = NEW_URL
+ "/service-myverification-link/v1/link/verify";
private ApiEndPoint() {
// This class is not publicly instantiable
}
}
For the code above, I was wondering how do i make the NEW_URL link more dynamic, seems like its sticking to the value saved first time and does not change after. I need to keep this link static due to :
#Override
public Single<LoginResponse> doServerLoginApiCall(LoginRequest request) {
return Rx2AndroidNetworking.post(ApiEndPoint.ENDPOINT_SERVER_LOGIN)
.doNotCacheResponse()
.addBodyParameter(request)
.build()
.getObjectSingle(LoginResponse.class);
}
Any idea, how I can fix this so I can update the link in NEW_URL every single time that it sticks to the new value instead of the value stored the first time?
You will need to use the onSharedPreferenceChangeListener
SharedPreferencesHelper.getSharedPreferences(context).registerOnSharedPreferenceChangeListener(
new SharedPreferences.OnSharedPreferenceChangeListener() {
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
if(key.equals("SOME_STRING_VALUE")){
NEW_URL = prefs.getString("SOME_STRING_VALUE" , null);
}
}
});
Why don't you send the Url as a parameter every time:
#Override
public Single<LoginResponse> doServerLoginApiCall(LoginRequest request, String url) {
return Rx2AndroidNetworking.post(url)
.doNotCacheResponse()
.addBodyParameter(request)
.build()
.getObjectSingle(LoginResponse.class);
}
Method call:
doServerLoginApiCall(request, SharedPreferencesHelper.getSomeStringValue(getApplicationContext()) + ENDPOINT);

How to update Activity's textview when returning from another Activity's RecyclerView?

Hello (First of all excuse my English if something is wrong, it's not my first language), I'm developing an app with the IMDB API to keep up to date with your favorite series (no links or anything illegal).
I'm gonna focus on the two activities in which the problem is: The first Activity, ActivitySerieJson contains a recycled view filled with all the seasons in card view. Each card view contains season thumbnail, season number and the users completed view percentage:
ActivitySerieJson.
The second activity, ActivityTemporadaJSON contains another recyclerview, this one is filled with chapters name, thumbnail and an eye-shaped button that, when pressed, marks the chapter as seen on DB. The problem is that when I go back to previous activity the completed view percentage TextView is not being refreshed.
ActivityTemporadaJSon
This is my code:
RecyclerAdapterTemporada
public void bindPhoto(Temporada mtemporada, String idSerie, String tipo) {
temporada = mtemporada;
String Nombre = temporada.getNombreTemporada();
if(Nombre.length() >= 25)
{
Nombre = Nombre.substring(0,22);
Nombre = Nombre + "...";
}
AQuery androidAQuery=new AQuery(mItemImage.getContext());
androidAQuery.id(mItemImage).image(temporada.getPoster(), true, true, 150,0);
//Picasso.with(mItemImage.getContext()).load(mserie.getPoster()).into(mItemImage);
mItemDate.setText(Nombre);
mItemidTMDB.setText(idSerie);
mItemNumTemp.setText(Integer.toString(temporada.getNumeroTemporada()));
mItemNumEps.setText(Integer.toString(temporada.getNumeroEpisodios()));
//THIS CODE SECTION CALCULATES PERCENTAGE
if(tipo.equalsIgnoreCase("SQL"))
{
int porcen=1;
int numEps = temporada.getNumeroEpisodios();
if(numEps == 0){
numEps = 1;
}
porcen = (temporada.getEpisodiosVsitos() * 100) / numEps;
mNumEpsVistoVal.setText(Integer.toString(porcen) + "%");
}
else
{
mNumEpsVisto.setVisibility(View.INVISIBLE);
mNumEpsVistoVal.setVisibility(View.INVISIBLE);
}
}
}
}
RecyclerAdapterEpisodio
public class RecyclerAdapterEpisodio extends
RecyclerView.Adapter<RecyclerAdapterEpisodio.EpisodioHolder> {
private ArrayList<Episodio> mEpisodio;
private int IdSerie;
private RecyclerAdapterEpisodio miAdaptador;
private String Tipo;
private View v;
//5
#Override
public void onClick(View v) {
/*Context context = itemView.getContext();
Intent showPhotoIntent = new Intent(context, Pelicula.class);
showPhotoIntent.putExtra(PHOTO_KEY, peli);
context.startActivity(showPhotoIntent);*/
}
public void bindPhoto(final Episodio mEpisodio, final int mIdSerie, String tipo) {
episodio = mEpisodio;
if (tipo.equalsIgnoreCase("SQL")) {
if(episodio.isVisto()){
mBoton.setBackgroundResource(R.drawable.ojoabierto);
}else{
mBoton.setBackgroundResource(R.drawable.ojocerrado);
}
mBoton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (episodio.isVisto()) {
//mBoton.setBackgroundResource(R.drawable.ojoabierto);
DBHelper mydb = new DBHelper(v.getContext());
mydb.CancelVerEpisodio(episodio.getIdEpisodio());
v.setBackgroundResource(R.drawable.ojocerrado);
episodio.setVisto(false);
} else//else
{
//mBoton.setBackgroundResource(R.drawable.ojocerrado);
DBHelper mydb = new DBHelper(v.getContext());
mydb.VerEpisodio(episodio.getIdEpisodio());
mBoton.setBackgroundResource(R.drawable.ojoabierto);
episodio.setVisto(true);
}
}
});
}
else
{
mBoton.setVisibility(View.INVISIBLE);
}
in your fist activity do the loading inside OnResume(). so that when you comeback to the activity . onResume() method will be first called and you will get the updated data. This is when you have all your other block codes functioning well but you have problem with refreshing your page.
move your loading method from onCreate() to onResume() in the first activity

how to reload listview from another activity (adapter) class

i have tried all the things but i cant get proper result,i also try
adapter.clearAll()
adapter.notifyDataSetChanged()
but i cant get result when i delete row from list view its deleted from its position but when i change value of another row than the delete process working perfectly but changed value not set.getting value from database perfectly.
Here is my code please help me and tell where i m doing wrong.
Thank you in advance
Delete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String Identifier_fev = null;
String Default_Option = null;
String Quantity1 = null;
jffDatabase.open();
Cursor identifie = jffDatabase.getALL();
if (identifie.moveToPosition(position)) {
Identifier_fev = identifie.getString(identifie.getColumnIndexOrThrow("identifier"));
Default_Option = identifie.getString(identifie.getColumnIndexOrThrow("default_option"));
}
jffDatabase.delete(Identifier_fev, Default_Option);
identifier.remove(position);
title.remove(position);
defaultPrice.remove(position);
default_option.remove(position);
price.remove(position);
quantity.remove(position);
Cursor c1 = jffDatabase.getALL();
if (c1.moveToFirst()) {
do {
Quantity1 = c1.getString(c1.getColumnIndexOrThrow("quantity"));
update_quantity.add(Quantity1);
} while (c1.moveToNext());
}
for (int i = 0; i < update_quantity.size(); i++) {
Toast.makeText(ctx, "" + update_quantity, Toast.LENGTH_LONG).show();
Quantitylbl.setText(update_quantity.get(i).toString());
Toast.makeText(ctx, "set " + Quantitylbl.getText().toString(), Toast.LENGTH_LONG).show();
}
Quantity();
notifyDataSetChanged()
AddtoCartActivity.Cartcount.setText(String.valueOf(sum));
}
});
Good practice is use Interface
Create new Interface
public interface MyCustomObjectListener {
public void RefreshList();
//add parameter for delete if required ex-
//public void RefreshList(String Item_id);
}
then implement Activity by this Interface
YourActivityName extends Activity implements MyCustomObjectListener
And Implement Method
#Override
public void RefreshList() {
// Do your delete task and clear current List and get updated list task here
}
and from Base adapter onClick you can call method RefreshList like this
((YourActivityName)mContext).RefreshList();
you can delete and refresh list from #Override RefreshList

Understanding and fixing instance handling between classes

Im having issues with the app crashing with nullpoint exception.
I know that it crashes when trying to get an ArrayList from pictureTalkFragment. which in this class is only set to PictureTalkFragment ptf;
In other words im trying to get an element (have both getter/setter for the arraylist in ptf, and made the arraylist public as an alternative) from an class and not the instance of that class.
But im just to noob to figure out how to correctly handle getting the instances between classes (activity ---> fragments and back etc). In Java i usually just had an referance in the Constructor that sent the instance/referance with the creation of the new class. But in Android theres all this onCreate (getActivity,getContext ++), Im confused:P When to user where and how:(
the EditPicture was started from this code in GridViewAdapter that extended from PictureTalkFragment (edit in onlongclicklistener)
row.setOnLongClickListener(new View.OnLongClickListener()
{
#Override
public boolean onLongClick(View v) {
PopupMenu popMenu = new PopupMenu(v.getContext(), v);
popMenu.getMenuInflater().inflate(R.menu.picturetalk_popup_menu, popMenu.getMenu());
popMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem menuItem) {
switch (menuItem.getItemId()) {
case R.id.edit:
Intent intent = new Intent(getContext(), EditPicture.class);
intent.putExtra("itemUUID", item.getId());
String s = new String("");
context.startActivity(intent);
break;
case R.id.remove:
FileInteraction fileInteraction = new FileInteraction();
fileInteraction.deleteFilesAndFolder(item.getImagePath());
item.setTitle("");
notifyDataSetChanged();
break;
default:
//
}
return true;
}
});
popMenu.show();
return true;
}
});
return row;
EditPicture class
public class EditPicture extends Activity {
private EditText text;
private Button applyBtn;
private ArrayList<PictureItem> piArray;
private PictureItem pi;
private UUID itemID;
private PictureTalkFragment ptf;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
itemID = (UUID) getIntent().getSerializableExtra("itemUUID");
SetLocalArray(ptf.getArray()); //Nullpoint here, and i know why. But not how to get the allready created instance of this class
getPictureItem();
setContentView(R.layout.picturetalk_edit_pic);
text = (EditText) findViewById(R.id.editName);
text.setText(pi.getTitle());
applyBtn = (Button) findViewById(R.id.applyChangeBtn);
applyBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
updatePictureItem();
ptf.setArray(piArray);
}
});
}
private void updatePictureItem() {
pi.setTitle(text.toString());
piArray.add(pi);
ptf.setArray(piArray);
}
private void SetLocalArray(ArrayList<PictureItem> array) {
this.piArray = array;
}
private PictureItem getPictureItem() {
pi = new PictureItem("", "");
for (int i = 0; i < piArray.size(); i++) {
if (itemID.equals(piArray.get(i))) {
pi = piArray.get(i);
piArray.remove(i);
}
}
return pi;
}}
I don't know what you are using the array for.
Usually you should not depend on the fragment to get the info, if you want to pass an array of objects to the activity, you should use the Bundle in the activity extras to do so, instead of passing only the UUID, just pass also the array you need.
If you want the lazy option just make a class with a static variable to store the fragment and use it in the activity, which I don't advise.

Categories

Resources