in my project, I have to use dialogs in different parts of the app and the downside is same code for creating and showing the Dialog used every time! So I decided to make a function for creating and showing a dialog and wherever I need I just call that,
the problem is, there are 2 buttons on my Dialog and before refactoring on the onClickListener I could easily use
dialog.dismiss();
// more codes ...
in setOnClickListener
but now with the incoming OnClickListener Object, I have no control over the dialog instance ...
this is the function I wrote
public static void warningAndErrorDialog(Activity activity, int titleResourceId, int iconResourceId, int contentResourceId
, HashMap<CustomDialogButton, View.OnClickListener> buttons) {
Typeface iranSansFont = setFont(activity, FontStyle.IRAN_SANS_REGULAR);
final Dialog dialog = new Dialog(activity);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(R.layout.dialog);
CustomFontTextView cftvTitle = (CustomFontTextView)
dialog.findViewById(R.id.txtViwDialogTitle);
if(activity.getString(titleResourceId) != null)
cftvTitle.setText(titleResourceId);
else cftvTitle.setText(" ");
CustomFontTextView cftvContent = (CustomFontTextView)
dialog.findViewById(R.id.txtViwDialogContent);
if(activity.getString(contentResourceId) != null)
cftvContent.setText(contentResourceId);
else cftvTitle.setText(" ");
ImageView imgViwDialogTitle = dialog.findViewById(R.id.imgViwDialogTitle);
imgViwDialogTitle.setImageResource(iconResourceId);
Button btnYes = null;
Button btnNo = null;
for (Map.Entry<CustomDialogButton, View.OnClickListener> button : buttons.entrySet())
switch (button.getKey()) {
case YES:
if (btnYes != null) break;
btnYes = dialog.findViewById(R.id.btnYes);
btnYes.setTypeface(iranSansFont);
if (button.getValue() != null)
btnYes.setOnClickListener(button.getValue());
break;
case NO:
if (btnNo != null) break;
btnNo = dialog.findViewById(R.id.btnNo);
if (button.getValue() != null) {
btnNo.setTypeface(iranSansFont);
btnNo.setOnClickListener(button.getValue());
} else
btnNo.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
dialog.dismiss();
}
});
break;
case OK:
btnYes = dialog.findViewById(R.id.btnYes);
btnYes.setText(R.string.ok);
if (button.getValue() != null) btnYes.setOnClickListener(button.getValue());
else
btnYes.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
dialog.dismiss();
}
});
btnNo = dialog.findViewById(R.id.btnNo);
btnNo.setVisibility(View.INVISIBLE);
return;
}
dialog.show();
}
notice of case YES:
I set button setOnClickListener from an onClickListener I passed to the function.
so I have no control over its content. now How Can I add statement dialog.dismiss(); ?
the Only thing I can think of is finding a way to pass an array of OnClickListener to the setOnCLickListener method.
one for dismissing the dialog and another one for setting the actual job of the button...
ps: I tried dismissing the dialog using setOnTouchListener but as I expected, that did not work...: -?
so what should I do?
final edit :
someone suggested
btnYes.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
for (View.OnClickListener callback : callbacks)
if (callback != null)
callback.onClick(view);
}
});
(callbacks is a List of View.OnClickListener object) and thats the exact answer to "how to add multiple onClickListener on a single Button" question.
but #greenapps solution is the best solution that suits my need, thanks :)
so I share the final version of the code for whom the may concern :D :
public class CustomDialog {
private final Dialog dialog;
private Typeface font;
private CustomFontTextView cftvTitle;
private CustomFontTextView cftvContent;
private ImageView imgViwDialogTitle;
private Activity activity;
private Button btnYes;
private Button btnNo;
public CustomDialog(final Activity activity, int titleResourceId, int iconResourceId, int contentResourceId
, HashMap<CustomDialogButton, View.OnClickListener> buttons) {
font = Utility.setFont(activity, FontStyle.IRAN_SANS_REGULAR);
this.activity = activity;
dialog = new Dialog(this.activity);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(R.layout.dialog);
setTitleTextbyId(titleResourceId);
setContentTextById(contentResourceId);
setTitleIconById(iconResourceId);
setButtons(buttons);
}
public CustomDialog(Activity activity) {
font = Utility.setFont(activity, FontStyle.IRAN_SANS_REGULAR);
this.activity = activity;
dialog = new Dialog(this.activity);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(R.layout.dialog);
setTitleTextbyId(0);
setContentTextById(0);
setTitleIconById(0);
setButtons(null);
}
public void show() {
dialog.show();
}
public void setButtons(HashMap<CustomDialogButton, View.OnClickListener> buttons) {
for (final Map.Entry<CustomDialogButton, View.OnClickListener> button : buttons.entrySet())
switch (button.getKey()) {
case YES:
setButtonYes(button);
break;
case NO:
setButtonNo(button);
break;
case OK:
setButtonYes(button);
btnYes.setText(R.string.ok);
btnNo = dialog.findViewById(R.id.btnNo);
btnNo.setVisibility(View.INVISIBLE);
break;
}
}
#NonNull
private void setButtonNo(final Map.Entry<CustomDialogButton, View.OnClickListener> button) {
if (btnNo != null) return;
btnNo = dialog.findViewById(R.id.btnNo);
btnNo.setTypeface(font);
btnNo.setOnClickListener(button.getValue());
btnNo.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
dialog.dismiss();
if(button.getValue() != null)
button.getValue().onClick(view);
}
});
}
#NonNull
private void setButtonYes(final Map.Entry<CustomDialogButton, View.OnClickListener> button) {
if (btnYes != null) return;
btnYes = dialog.findViewById(R.id.btnYes);
btnYes.setTypeface(font);
btnYes.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
dialog.dismiss();
if(button.getValue() != null)
button.getValue().onClick(view);
}
});
}
public void setTitleIconById(int iconResourceId) {
this.imgViwDialogTitle = dialog.findViewById(R.id.imgViwDialogTitle);
if (activity.getResources().getDrawable(iconResourceId) != null)
imgViwDialogTitle.setImageResource(iconResourceId);
}
public void setContentTextById(int contentResourceId) {
this.cftvContent = (CustomFontTextView)
this.dialog.findViewById(R.id.txtViwDialogContent);
if (this.activity.getString(contentResourceId) != null)
cftvContent.setText(contentResourceId);
else cftvTitle.setText(" ");
}
public void setTitleTextbyId(int titleResourceId) {
this.cftvTitle = (CustomFontTextView)
this.dialog.findViewById(R.id.txtViwDialogTitle);
if (this.activity.getString(titleResourceId) != null)
cftvTitle.setText(titleResourceId);
else cftvTitle.setText(" ");
}
public void dismiss() {
dialog.dismiss();
}
}
btnYes.setOnClickListener(button.getValue());
Change to:
btnYes.setOnClickListener(new View.OnClickListener() {
#Override public void onClick(View view) {
dialog.dismiss();
button.getValue().onClick(view);
}
});
Related
I've been stuck in a situation and i need some help over here. There are many articles on this topic here but none of them answered my question. I want to implement onBackPressed() in fragments and show dialog box which shows to exit the application or not. Any help would be appreciated.
LoginFragment.java
public class LoginFragment extends Fragment {
public static final String TAG = LoginFragment.class.getSimpleName();
private EditText mEtEmail;
private EditText mEtPassword;
private Button mBtLogin;
private TextView mTvRegister;
private TextView mTvForgotPassword;
private TextInputLayout mTiEmail;
private TextInputLayout mTiPassword;
private ProgressBar mProgressBar;
private CompositeSubscription mSubscriptions;
private SharedPreferences mSharedPreferences;
#NonNull
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_login,container,false);
mSubscriptions = new CompositeSubscription();
initViews(view);
initSharedPreferences();
return view;
}
private void initViews(View v) {
mEtEmail = v.findViewById(R.id.et_email);
mEtPassword = v.findViewById(R.id.et_password);
mBtLogin = v.findViewById(R.id.btn_login);
mTiEmail = v.findViewById(R.id.ti_email);
mTiPassword = v.findViewById(R.id.ti_password);
mProgressBar = v.findViewById(R.id.progress);
mTvRegister = v.findViewById(R.id.tv_register);
mTvForgotPassword = v.findViewById(R.id.tv_forgot_password);
mBtLogin.setOnClickListener(view -> login());
mTvRegister.setOnClickListener(view -> goToRegister());
mTvForgotPassword.setOnClickListener(view -> showDialog());
}
private void initSharedPreferences() {
mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
}
private void login() {
setError();
String email = mEtEmail.getText().toString();
String password = mEtPassword.getText().toString();
int err = 0;
if (!validateEmail(email)) {
err++;
mTiEmail.setError("Email should be valid !");
}
if (!validateFields(password)) {
err++;
mTiPassword.setError("Password should not be empty !");
}
if (err == 0) {
loginProcess(email,password);
mProgressBar.setVisibility(View.VISIBLE);
} else {
showSnackBarMessage("Enter Valid Details !");
}
}
private void setError() {
mTiEmail.setError(null);
mTiPassword.setError(null);
}
private void loginProcess(String email, String password) {
mSubscriptions.add(NetworkUtil.getRetrofit(email, password).login()
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(this::handleResponse,this::handleError));
}
private void handleResponse(Response response) {
mProgressBar.setVisibility(View.GONE);
SharedPreferences.Editor editor = mSharedPreferences.edit();
editor.putString(Constants.TOKEN,response.getToken());
editor.putString(Constants.EMAIL,response.getMessage());
editor.apply();
mEtEmail.setText(null);
mEtPassword.setText(null);
Intent intent = new Intent(getActivity(), HomeActivity.class);
startActivity(intent);
}
private void handleError(Throwable error) {
mProgressBar.setVisibility(View.GONE);
if (error instanceof HttpException) {
Gson gson = new GsonBuilder().create();
try {
String errorBody = ((HttpException) error).response().errorBody().string();
Response response = gson.fromJson(errorBody,Response.class);
showSnackBarMessage(response.getMessage());
} catch (IOException e) {
e.printStackTrace();
}
} else {
showSnackBarMessage("No Internet Connection!");
}
}
private void showSnackBarMessage(String message) {
if (getView() != null) {
Snackbar.make(getView(),message,Snackbar.LENGTH_SHORT).show();
}
}
private void goToRegister(){
FragmentTransaction ft = getFragmentManager().beginTransaction();
RegisterFragment fragment = new RegisterFragment();
ft.replace(R.id.fragmentFrame,fragment,RegisterFragment.TAG);
ft.addToBackStack(null).commit();
}
private void showDialog(){
ResetPasswordDialog fragment = new ResetPasswordDialog();
fragment.show(getFragmentManager(), ResetPasswordDialog.TAG);
}
#Override
public void onDestroy() {
super.onDestroy();
mSubscriptions.unsubscribe();
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity implements ResetPasswordDialog.Listener {
public static final String TAG = MainActivity.class.getSimpleName();
private LoginFragment mLoginFragment;
private ResetPasswordDialog mResetPasswordDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
loadFragment();
}
}
private void loadFragment() {
if (mLoginFragment == null) {
mLoginFragment = new LoginFragment();
}
getFragmentManager().beginTransaction().replace(R.id.fragmentFrame, mLoginFragment, LoginFragment.TAG).commit();
}
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
String data = intent.getData().getLastPathSegment();
Log.d(TAG, "onNewIntent: " + data);
mResetPasswordDialog = (ResetPasswordDialog) getFragmentManager().findFragmentByTag(ResetPasswordDialog.TAG);
if (mResetPasswordDialog != null)
mResetPasswordDialog.setToken(data);
}
#Override
public void onPasswordReset(String message) {
showSnackBarMessage(message);
}
private void showSnackBarMessage(String message) {
Snackbar.make(findViewById(R.id.activity_main), message, Snackbar.LENGTH_SHORT).show();
}
}
In My Login Fragment, I want to show a dialog box "Do you want to exit the application or not". On Yes it dismiss the current fragment and end the activity otherwise it'll remain active. Help please!
You can even try this way
MainActivity.java
#Override
public void onBackPressed() {
if (getFragmentManager() != null && getFragmentManager().getBackStackEntryCount() >= 1) {
String fragmentTag = getFragmentManager().findFragmentById(R.id.frame_container).getTag();
if(fragmentTag.equals(LoginFragment.getTag())){
// show Dialog code
}else{
super.onBackPressed();
}
} else {
super.onBackPressed();
}
}
Add this code in your main activity so that when login fragment is added and you click backpress, then on first if the fragment is added to fragment transaction, then first it finds the fragment and check if its tag is equals to the login fragment tag. Then if both tag matches, then you can show your exit alert dialog.
Android team has prepared a new way of handling the back button pressed on Fragments for us, so you should check this out. It's called OnBackPressedDispatcher.
You need to register OnBackPressedCallback to the fragment where do you want to intercept back button pressed. You can do it like this inside of the Fragment:
#Override
public void onAttach(#NonNull Context context) {
super.onAttach(context);
OnBackPressedCallback callback = new OnBackPressedCallback(true) {
#Override
public void handleOnBackPressed() {
//show exit dialog
}
};
requireActivity().getOnBackPressedDispatcher().addCallback(this, callback);
}
This question already has an answer here:
android rotating screen causes text colour to change to default
(1 answer)
Closed 4 years ago.
I am having a slight issue with my android app where the text colour changes back to a default color once I rotate my screen.
Basically I have an if statement where if Player one makes a move in selecting a button (12 buttons altogether), their selection is displayed as a particular colour, if it's not player one's move then it must be Player two where their selection is marked as a different text colour.
#Override
public void onClick(View v) {
if (!((Button) v).getText().toString().equals("")) {
return;
}
if (playerOneMove) {
((Button) v).setText("A");
((Button) v).setTextColor(Color.parseColor("#e8e5e5"));
} else {
((Button) v).setText("Z");
((Button) v).setTextColor(Color.parseColor("#737374"));
}
...
}
The above code is within OnCreate(). How can I keep my test colour within rotation? I know there is protected void onSaveInstanceState(Bundle outState) and protected void onRestoreInstanceState(Bundle savedInstanceState) but how do I call on my buttons within them?
UPDATE
private Button btnObj1;
private Button btnObj2;
private Button btnObj3;
private Button btnObj4;
private Button btnObj5;
private Button btnObj6;
private Button btnObj7;
private Button btnObj8;
private Button btnObj9;
private static final String TEXT_COLOR = "textColor";
private String textColor;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
textColor = savedInstanceState.getString(TEXT_COLOR);
if(btnObj1 != null) {
btnObj1.setTextColor(Color.parseColor(textColor));
}
if (btnObj2 != null) {
btnObj2.setTextColor(Color.parseColor(textColor));
}
if (btnObj3 != null) {
btnObj3.setTextColor(Color.parseColor(textColor));
}
if (btnObj4 != null) {
btnObj4.setTextColor(Color.parseColor(textColor));
}
if (btnObj5 != null) {
btnObj5.setTextColor(Color.parseColor(textColor));
}
if (btnObj6 != null) {
btnObj6.setTextColor(Color.parseColor(textColor));
}
if (btnObj7 != null) {
btnObj7.setTextColor(Color.parseColor(textColor));
}
if (btnObj8 != null) {
btnObj8.setTextColor(Color.parseColor(textColor));
}
if (btnObj9 != null) {
btnObj9.setTextColor(Color.parseColor(textColor));
}
}
if (savedInstanceState != null) {
textColor = savedInstanceState.getString(TEXT_COLOR);
btnObj1.setTextColor(Color.parseColor(textColor));
btnObj2.setTextColor(Color.parseColor(textColor));
btnObj3.setTextColor(Color.parseColor(textColor));
btnObj4.setTextColor(Color.parseColor(textColor));
btnObj5.setTextColor(Color.parseColor(textColor));
btnObj6.setTextColor(Color.parseColor(textColor));
btnObj7.setTextColor(Color.parseColor(textColor));
btnObj8.setTextColor(Color.parseColor(textColor));
btnObj9.setTextColor(Color.parseColor(textColor));
}
setContentView(R.layout.activity_main_player2);
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
String buttonID = "button_" + i + j;
int resID = getResources().getIdentifier(buttonID, "id", getPackageName());
buttons[i][j] = findViewById(resID);
buttons[i][j].setOnClickListener(this);
}
}
#Override
public void onClick(View v) {
if (!((Button) v).getText().toString().equals("")) {
return;
}
if (playerOneMove) {
((Button) v).setText("A");
textColor = "#e8e5e5";
((Button) v).setTextColor(Color.parseColor(textColor));
} else {
((Button) v).setText("Z");
textColor = "#737374";
((Button) v).setTextColor(Color.parseColor(textColor));
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
outState.putBoolean("playerOneMove", playerOneMove);
outState.putString(TEXT_COLOR, textColor);
super.onSaveInstanceState(outState);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
playerOneMove = savedInstanceState.getBoolean("playerOneMove");
textColor = savedInstanceState.getString(TEXT_COLOR);
super.onRestoreInstanceState(savedInstanceState);
}
Thanks
Whenever screen is rotated and you are not handling the configuration changes, your activity will be re-created as a result all the state of your views won't be maintained. If you can use onSaveInstanceState to store the state as follows:
private static final String TEXT_COLOR = "TEXT_COLOR";
private String textColor;
private Button btnObj;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
btnObj = findViewById(<button id>);
if (savedInstanceState != null) {
textColor = savedInstanceState.getString(TEXT_COLOR);
btnObj.setTextColor(Color.parseColor(textColor));
}
...
}
#Override
public void onClick(View v) {
if (!((Button) v).getText().toString().equals("")) {
return;
}
if (playerOneMove) {
((Button) v).setText("A");
textColor = "#e8e5e5";
((Button) v).setTextColor(Color.parseColor(textColor));
} else {
((Button) v).setText("Z");
textColor = "#737374";
((Button) v).setTextColor(Color.parseColor(textColor));
}
...
}
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putString(TEXT_COLOR, textColor);
super.onSaveInstanceState(savedInstanceState);
}
whenever I use the app switcher or the app gets paused in any other way then upon resuming it I will get a NullPointerException when trying to use findViewById in my fragment. The same happens when trying to use getActivity() or anything related to the Main activity. I've tried checking of the fragment is attached or not with isAdded() and it returns true but still gives the error. (Don't mind the way the code looks, I still need to clean it up)
All irrelevant classes and methods are not included (ex. Profanity class).
MainActivity onStart method (Launch activity)
#Override
public void onStart() {
super.onStart();
Profanity.downloadList();
if (AskForPermissions()) {
if (mAuth.getCurrentUser() != null) {
mAuth.getCurrentUser().reload().addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.MainFragment, new LoginFragment()).commit();
}
}).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.MainFragment, new HomeFragment()).commit();
}
});
} else {
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.MainFragment, new LoginFragment()).commit();
}
} else {
onStart();
}
}
HomeFragment (The one that crashes, crash happens under Started() on the 4th line)
#SuppressWarnings("all")
#Override
public void onStart() {
super.onStart();
loadVariables();
final String UUID = ((MainActivity) getActivity()).mAuth.getCurrentUser().getUid();
User.UUID = UUID;
if (User.userName == null || User.userName.equals("")) {
Functions.loadUserData(UUID).addOnCompleteListener(new OnCompleteListener() {
#Override
public void onComplete(#NonNull Task task) {
if (task.getResult() == null) {
final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Choose your username");
final EditText input = new EditText(getActivity());
input.setInputType(InputType.TYPE_CLASS_TEXT);
builder.setView(input);
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
}
});
final AlertDialog dialog = builder.create();
dialog.show();
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (input.getText() != null && !input.getText().toString().equals("") && !input.getText().toString().equals(" ")) {
if (input.getText().toString().toCharArray().length > 16) {
dialog.dismiss();
Functions.showBottomMessage(getView(), "Your username must be maximum 16 characters.");
dialog.show();
} else if (Profanity.contains(input.getText().toString())) {
dialog.dismiss();
Functions.showBottomMessage(getView(), "Please refrain from using restricted words in your username.");
input.setText("");
dialog.show();
} else {
User.userName = input.getText().toString();
dialog.dismiss();
FirebaseReferences.users.child(User.UUID).child("name").setValue(User.userName);
Functions.showBottomMessage(getView(), "Username saved.");
}
} else {
dialog.dismiss();
Functions.showBottomMessage(getView(), "Please enter a valid username.");
dialog.show();
}
}
});
Started();
} else {
HashMap temp = (HashMap) task.getResult();
if (temp.containsKey("name")) {
User.userName = temp.get("name").toString();
} else {
final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Choose your username");
final EditText input = new EditText(getActivity());
input.setInputType(InputType.TYPE_CLASS_TEXT);
builder.setView(input);
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
}
});
final AlertDialog dialog = builder.create();
dialog.show();
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (input.getText() != null && !input.getText().toString().equals("") && !input.getText().toString().equals(" ")) {
User.userName = input.getText().toString();
dialog.dismiss();
FirebaseReferences.users.child(UUID).child("name").setValue(input.getText().toString());
} else {
dialog.dismiss();
dialog.show();
}
}
});
}
if (temp.containsKey("place")) {
User.place = temp.get("place").toString();
}
if (temp.containsKey("ratedImages")) {
User.ratedImages = (ArrayList<String>) temp.get("ratedImages");
}
if (temp.containsKey("developer")) {
if (Boolean.valueOf(temp.get("developer").toString().toLowerCase()))
User.isDeveloper = true;
}
Started();
}
}
});
} else {
Started();
}
}
#SuppressWarnings("all")
private void Started() {
mainImageProgressBar.setVisibility(View.VISIBLE);
secondaryImageProgressBar.setVisibility(View.VISIBLE);
CacheHandler.update(getActivity(), imageView, secondImageView, true);
/*THIS IS THE FIRST CRASH POINT - */getView().findViewById(R.id.fabSendImage).setOnClickListener(getBtnSendImageOnClickListener());
getView().findViewById(R.id.btnReportImage).setOnClickListener(btnReportImageOnClick);
}
All view related code must be moved on to onCreateView(). So just place your code to onCreateView in case of fragment and onCreate in case of activity.
For more info just go through https://developer.android.com/guide/components/fragments.html
Crashing because of getView(). Because its not able get the view.
You need to pass the view which hold the view with id R.id.fabSendImage and try calling the view.findViewById(R.id.fabSendImage) to initialize.
This is the demo code and when I add onClickListener in fill function it is not working and if i set any other property like background color it works fine.
private void fillHolder(FriendsHolder holder, final Friend friend) {
if (friend == null)
return;
Iterator<Button> iViews = holder.interests.iterator();
Iterator<String> iInterests = friend.getInterests().iterator();
while (iViews.hasNext() && iInterests.hasNext()) {
iViews.next().setText(iInterests.next());
}
Iterator<Button> iViewss = holder.interests.iterator();
while (iViewss.hasNext()) {
iViewss.next().setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getActivity(), friend.getNickname(), Toast.LENGTH_SHORT).show();
}
});
}
holder.infoPage.setBackgroundColor(getResources().getColor(friend.getBackground()));
holder.nickName.setText(friend.getNickname());
}
}
You're iterating through iViewss (with double S in the end) and you're setting the listener to iViews(with single S in the end).
It's not the same object.
iViews.next().setOnClickListener() will throw a NoSuchElementException because there is not a next element.
Change your code like that:
private void fillHolder(FriendsHolder holder, final Friend friend) {
if (friend == null)
return;
Iterator<Button> iViews = holder.interests.iterator();
Iterator<String> iInterests = friend.getInterests().iterator();
while (iViews.hasNext() && iInterests.hasNext()) {
iViews.next().setText(iInterests.next());
}
while (iViews.hasNext()) {
iViews.next().setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getActivity(), friend.getNickname(), Toast.LENGTH_SHORT).show();
}
});
}
holder.infoPage.setBackgroundColor(getResources().getColor(friend.getBackground()));
holder.nickName.setText(friend.getNickname());
}
EDIT:
You can also combine the two while-loops (as cricket_007 suggestion):
private void fillHolder(FriendsHolder holder, final Friend friend) {
if (friend == null)
return;
Iterator<Button> iViews = holder.interests.iterator();
Iterator<String> iInterests = friend.getInterests().iterator();
while (iViews.hasNext()) {
Button button = iViews.next();
if (iInterests.hasNext()) {
button.setText(iInterests.next());
}
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getActivity(), friend.getNickname(), Toast.LENGTH_SHORT).show();
}
});
}
holder.infoPage.setBackgroundColor(getResources().getColor(friend.getBackground()));
holder.nickName.setText(friend.getNickname());
}
Along with the comments from the other answer, I think this code is more appropriate - it looks like you can combine the while-loops.
private void fillHolder(FriendsHolder holder, final Friend friend) {
if (friend == null)
return;
Iterator<Button> iViews = holder.interests.iterator();
Iterator<String> iInterests = friend.getInterests().iterator();
while (iViews.hasNext()) {
Button nextButton = iViews.next();
if (iInterests.hasNext()) {
nextButton.setText(iInterests.next());
}
nextButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getActivity(), friend.getNickname(), Toast.LENGTH_SHORT).show();
}
});
}
holder.infoPage.setBackgroundColor(getResources().getColor(friend.getBackground()));
holder.nickName.setText(friend.getNickname());
}
I have 2 activities. In the first one i choose a level. In the second i play the game.In the second activity I answer questions and everytime I answer correctly I add one value to my arraylist. When the game ends a user goes back to level select activity and there he can see his score. For example: Level1: you answered 17 questions correctly. How can I achieve that? I tried using sharedpreferences but had no luck. It always shows 0. Im guessing its because it gets the value at the start of the game, when the list is empty. How to show the values after the game has ended when the list is filled?
This is the game activity in witch I create a list, store values in it and answer questions.:
public class MainActivity extends Activity {
Button mYes;
Button mNo;
TextView mQuestion;
Button btnClosePopup;
TextView mPopupText;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final int[] count = {0}; // Global array.
final int[] score = {0};
//final int[] intArray = new int[3];
mYes = (Button) findViewById(R.id.button2);
mPopupText = (TextView)findViewById(R.id.popupTekstas);
btnClosePopup = (Button)findViewById(R.id.btn_close_popup);
mNo = (Button) findViewById(R.id.button);
mQuestion = (TextView) findViewById(R.id.textView);
//Creating questions. (Question, boolean, answer).
final Question first = new Question("Do i understand this code?", true, "Only Jesus knows");
final Question second = new Question("Why dont i understand this code?", false, "Im not Jesus");
final Question third = new Question("Why I am not Jesus?", true, "2fat.");
//Creating Lists for questions and boolean values.
final ArrayList<Question> questions = new ArrayList<Question>();
final ArrayList<Boolean> type = new ArrayList<Boolean>();
final ArrayList<Integer> points = new ArrayList<Integer>();
SharedPreferences sharedPref = getSharedPreferences("level1", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putInt("taskai", points.size());
editor.commit();
//mResult.setText("zdr");
//Adding questions to the question list
questions.add(first);
questions.add(second);
questions.add(third);
// Adding boleans to the boolean list
type.add(first.correctAnswer);
type.add(second.correctAnswer);
type.add(third.correctAnswer);
//Show the first question on Activity start.
mQuestion.setText(questions.get(0).question);
// Open PopUp Window on true button click.
mYes.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
initiatePopupWindow();
if(type.get(count[0])){
((TextView)pwindo.getContentView().findViewById(R.id.popupTekstasTiesaArNe)).setText("Correct!");
} else {
((TextView)pwindo.getContentView().findViewById(R.id.popupTekstasTiesaArNe)).setText("False!");
}
//Show the first answer on first button click.
((TextView)pwindo.getContentView().findViewById(R.id.popupTekstas)).setText(questions.get((count[0]) % questions.size()).answer);
// When PopUp button closes open the next question with the if/else conditions.
btnClosePopup.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//if the question is true show next question/ else close app
if (type.get(count[0])) {
points.add(1); // if the answer is correct add +1 to the list.
score[0]++;
if(questions.size()-1 == count[0]) // if you count[0] is init to 0
{
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("WInner");
builder.setMessage("You won, play again?");
builder.setCancelable(false);
builder.setPositiveButton(android.R.string.yes,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// just close dialog
dialog.cancel();
}
});
builder.setNegativeButton(android.R.string.no,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
finish();
// mResult.setText("" + points.size());
}
});
// Create dialog from builder
AlertDialog alert = builder.create();
// Show dialog
alert.show();
count[0]=0;
}
else if(questions.size()-1 < count[0])
try {
throw new Exception("Invalid ");
} catch (Exception e) {
e.printStackTrace();
}
else
count[0]++;
mQuestion.setText(questions.get(count[0]).question); // you dont need calculate the module anymore
pwindo.dismiss();
} else {
count[0]++;
mQuestion.setText(questions.get(count[0]).question); // you dont need calculate the module anymore
pwindo.dismiss();
}
}
});
}
});
mNo.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
initiatePopupWindow();
if(!type.get(count[0])){
((TextView)pwindo.getContentView().findViewById(R.id.popupTekstasTiesaArNe)).setText("Correct!");
} else {
((TextView)pwindo.getContentView().findViewById(R.id.popupTekstasTiesaArNe)).setText("False!");
}
((TextView)pwindo.getContentView().findViewById(R.id.popupTekstas)).setText(questions.get((count[0]) % questions.size()).answer);
btnClosePopup.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!type.get(count[0])) {
points.add(1); // if the answer is correct add +1 to the list.
score[0]++;
if(questions.size()-1 == count[0]) // if you count[0] is init to 0
{
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("WInner")
.setMessage("You won, play again?")
.setCancelable(false)
.setPositiveButton(android.R.string.yes,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// just close dialog
dialog.cancel();
}
})
.setNegativeButton(android.R.string.no,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
finish();
//mResult.setText("" + points.size());
}
});
// Create dialog from builder
AlertDialog alert = builder.create();
// Show dialog
alert.show();
count[0]=0;
((TextView)pwindo.getContentView().findViewById(R.id.popupTekstasTiesaArNe)).setText("Klaida!");
}
else if(questions.size()-1 < count[0])
try {
throw new Exception("Invalid ");
} catch (Exception e) {
e.printStackTrace();
}
else
count[0]++;
mQuestion.setText(questions.get(count[0]).question); // you dont need calculate the module anymore
pwindo.dismiss();
} else {
count[0]++;
mQuestion.setText(questions.get(count[0]).question); // you dont need calculate the module anymore
pwindo.dismiss();
}
}
});
}
});
}
public PopupWindow pwindo;
public void initiatePopupWindow() {
try {
// We need to get the instance of the LayoutInflater
LayoutInflater inflater = (LayoutInflater) MainActivity.this
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.popup,
(ViewGroup) findViewById(R.id.popup_element));
pwindo = new PopupWindow(layout, 500, 570, true);
pwindo.showAtLocation(layout, Gravity.CENTER, 0, 0);
btnClosePopup = (Button) layout.findViewById(R.id.btn_close_popup);
btnClosePopup.setOnClickListener(cancel_button_click_listener);
} catch (Exception e) {
e.printStackTrace();
}
}
public View.OnClickListener cancel_button_click_listener = new View.OnClickListener() {
#Override
public void onClick(View v) {
pwindo.dismiss();
}
};
In this activity I try to get the list values and show them:
public class LevelSelectActivity extends MainActivity {
Button mLevel1;
public TextView mResult;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_level_select);
SharedPreferences sharedPref = getSharedPreferences("level1", Context.MODE_PRIVATE);
int result = sharedPref.getInt("taskai", 0);
mLevel1 = (Button)findViewById(R.id.level1);
mResult = (TextView)findViewById(R.id.Resultas);
// mResult.setText(players.size()-1 + "/" + 3);
mResult.setText("" + result);
mLevel1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent startGame = new Intent(LevelSelectActivity.this, MainActivity.class);
startActivity(startGame);
}
});
}
I don't know for sure what's happening in your code, but I do know preferences aren't the best way to pass data.
You are better off using a set results/ get results pattern.
The first activity uses
startActivityForResult(intent, LEVEL_REQUEST);
It will also create a function to read back the data after it is done. That'll look something like:
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// Check which request we're responding to
if (requestCode == LEVEL_REQUEST) {
// Make sure the request was successful
if (resultCode == RESULT_OK) {
}
}
}
The activity sending the results will do this to publish the results:
Intent resultsIntent=new Intent();
//Set data in the intent, note this intent is returned to the original function in `onActivityResult`
setResult(Activity.RESULT_OK,resultsIntent);
The second activity uses