Global value becomes null in method - java

I have created a private member of the whole class called Member curMbr;
The activity (rather the fragment, since this is in a frament class) has a listview
with some contributions from members.
I also have a context menu on that list. When clicking on a contribution, I want a (customized) dialog box to show details about the member. (Member ID is part of the contribution objet. )
#Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
Log.d("FRGCOTIZ02", "create ctxt menu");
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
String[] menuItems = getResources().getStringArray(R.array.ar_menu_ctxt_participant);
// Get selected member
Contribution curCotis = (Contribution) (((ListView)v).getItemAtPosition(info.position));
Participant p = new Participant(helper.getDBItem(DBHelper.TABLE_PARTICIPANT,
DBHelper.COL_ID, curCotis.getParticipant()));
curMbr = new Member(helper.getDBItem(DBHelper.TABLE_MEMBER, DBHelper.COL_ID, p.getMember()));
for (int i = 0; i < menuItems.length; i++) {
menu.add(Menu.NONE, i, i, menuItems[i]);
}
Log.d("FRGCOTIZ01", curMbr.getId_());
}
#Override
public boolean onContextItemSelected(MenuItem item) {
return ( applyContextMenuSelection(item) || super.onContextItemSelected(item) );
}
private boolean applyContextMenuSelection(MenuItem item) {
switch (item.getItemId()) {
case 0: // Summary
final Dialog dlg = new Dialog(this.getContext());
final String sessID;
try {
sessID = KUtil.DATE_FORMAT.format(curSess.getDate());
dlg.setContentView(R.layout.alert_show_charges);
Button btnOK = dlg.findViewById(R.id.btn_alertOK);
btnOK.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
setupAlertDialogCharges(dlg, sessID, curMbr.getId_());
}
});
Button btnCancel = dlg.findViewById(R.id.btn_alertCancel);
btnCancel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
dlg.dismiss();
}
});
dlg.show();
} catch (Exception e){
Log.d("FRAGMENT Contribution", e.getMessage());
}
break;
case 1: // Collect
break;
case 2: // Cancel
break;
default:
break;
}
return true;
}
In method onCreateContextMenu, I can get the member and display his ID.
But in method applyContextMenuSelection, there is an exception, saying the meber is null!
Funny enough there is another variable that I am using in that method, and it works fine. Difference is, that variable has been set at creation of the fragment.
How do I solve this?

I have been studying the code for a while and the only thing I could figure was that the issue is somehow linked to the use of contextmenu. It seems to me that variables are set back to their original when the menu action is supposed to be executed. Again, I am not too sure about that.
So, the only solution I found so far was to keep that vale in a "higher" context:
When I can still read the value,
getActivity().getIntent().putExtra(HomeActivity.ID_ENTRY, curMbr.getId_());
When I want to use it,
final String mbrID = getActivity().getIntent().getStringExtra(HomeActivity.ID_ENTRY);

Related

RecyclerView radio button won't register only the latest checked item (remember previous too)

I have RecyclerView which has multiple items, those items contain radio buttons, course name (TextView) and hole number (TextView).
What supposes to happen is that when I click the radio button, it should select only that 1, and if there are the previous check it should uncheck it (single selection). Well at the moment It checks only 1 at a time which is ok (so frontend works as it should), but what happens "under the hood"... example:
There are currently 3 items in RecyclerView. I click the third item to be checked, then I click first, and again third. now I click "start game" button, what should happen is that it should take that lastly checked item (in this case the third left lastly selected) and intent its course name and hole number to the next Activity, but instead what happens now is that it intent the first items course name and hole number... Also if I do the same as previous, but instead of clicking first item, I click second, then even tho lastly I clicked that third item, instead intent its course name and hole number, it intents that second items... So it always intents that item which is clicked (at some point) and from those clicked items it checks the first 1 (from top to bottom of a list) and take its intents.
Here is my Adapter where I'm checking which 1 is selected:
public class NewGameCourseAdapter extends RecyclerView.Adapter<NewGameCourseAdapter.NewGameCourseViewHolder> {
private ArrayList<NewGameCourseItem> mCourseList;
private NewGamePlayerAdapter.OnItemsCheckStateListener checkStateListener;
private NewGameCourseAdapter.OnItemClickListener itemClickListener;
public void setOnItemClickListener(NewGameCourseAdapter.OnItemClickListener listener) {
itemClickListener = listener;
}
public interface OnItemClickListener {
void onItemClick(int position);
}
public void setOnItemsCheckStateListener(NewGamePlayerAdapter.OnItemsCheckStateListener checkStateListener) {
this.checkStateListener = checkStateListener;
}
public static class NewGameCourseViewHolder extends RecyclerView.ViewHolder {
public RadioButton mRadioButton;
public NewGameCourseViewHolder(#NonNull View itemView, final NewGameCourseAdapter.OnItemClickListener listener) {
super(itemView);
mRadioButton = itemView.findViewById(R.id.radioButton);
}
}
onBindViewHolder:
#Override
public void onBindViewHolder(#NonNull final NewGameCourseViewHolder holder, final int position) {
final NewGameCourseItem currentItem = mCourseList.get(position);
/** This can prevent some unwanted actions in some cases **/
holder.mRadioButton.setOnCheckedChangeListener(null);
holder.mRadioButton.setChecked(selectedPosition == position);
holder.mRadioButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {
notifyItemChanged(selectedPosition);
selectedPosition = holder.getAdapterPosition();
notifyItemChanged(selectedPosition);
if (itemClickListener != null) {
itemClickListener.onItemClick(position);
}
}
});
This is the Activity where I do the intent:
mStartGame = findViewById(R.id.button_start_game);
mStartGame.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
for (int i = 0; i < mCourseList.size(); i++) {
/** If radio button is selected, then intent to ActivityGame **/
if (mCourseList.get(i).getRadioButton() == true) {
Intent intent = new Intent(ActivityNewGame2.this, ActivityGame.class);
/** Also intent selected items course name and hole number **/
intent.putExtra("COURSENAME", mCourseList.get(i).getCourseName());
intent.putExtra("HOLESNM", mCourseList.get(i).getHolesNm());
startActivity(intent);
overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left);
break;
}
}
}
});
Summary: in frontend it looks correct, it selects only that radio button which is lastly clicked and uncheck the previous (as it should), but inside, it won't "forget" the previous selections as it should do...
You are doing something weird, if possible make that simple.
Step 1: Create a method to get the selected item in your adapter class
public NewGameCourseItem getSelectedItem() {
return mCourseList.get(selectedPosition);
}
Step 2: Then modify your on click method like below
mStartGame.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
NewGameCourseItem item = adapter.getSelecteditem();
Intent intent = new Intent(ActivityNewGame2.this, ActivityGame.class);
/** Also intent selected items: course name and hole number **/
intent.putExtra("COURSENAME", item.getCourseName());
intent.putExtra("HOLESNM", item.getHolesNm());
startActivity(intent);
overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left);
}
});
Step 3: Now modify your onCheckedChanged as below
public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {
notifyItemChanged(selectedPosition);
selectedPosition = holder.getAdapterPosition();
notifyItemChanged(selectedPosition);
}
Create a class variable in adapter
private int selectedPosition = -1; //change -1 to any default position, need to be selected.
Modify the below function in adapter
#Override
public void onBindViewHolder(#NonNull final NewGameCourseViewHolder holder, final int position) {
final NewGameCourseItem currentItem = mCourseList.get(position);
holder.mRadioButton.setChecked(selectedPosition == position);
holder.mRadioButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {
if(isChecked) {
int tempSelected = selectedPosition;
selectedPosition = position;
notifyDataSetChanged();
}
}
});
}
Create a new method in adapter as below-
public int getSelectedItemIndex() {
return selectedPosition;
}
I assume adapter is the variable of NewGameCourseAdapter in the Activity class. Modify the button click in the Activity:
mStartGame.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
int selectedRecyclerItemPosition = adapter.getSelectedItemIndex();
//Calling intent and pass selected item info
Intent intent = new Intent(ActivityNewGame2.this, ActivityGame.class);
/** Also intent selected items course name and hole number **/
intent.putExtra("COURSENAME", mCourseList.get(selectedRecyclerItemPosition).getCourseName());
intent.putExtra("HOLESNM", mCourseList.get(selectedRecyclerItemPosition).getHolesNm());
startActivity(intent);
overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left);
}
});

Less than or Equal Condition Android

I have one quote application which has a "Load more" button visible only if the quote list size is 15. Now I want change the condition so that it must show the button only if the quote list size is more than 15. My current code is like below and I have tried to change it to:
if(c.getCount()<=15){
// Not Showing Load More Button
}
but it's not showing my button.
My code for that button is below:
final Button btnLoadMore=new Button(this);
btnLoadMore.setBackgroundColor(Color.parseColor("#351802"));
btnLoadMore.setTextColor(Color.parseColor("#e8d8a7"));
btnLoadMore.setTypeface(btnLoadMore.getTypeface(), Typeface.BOLD);
btnLoadMore.setText("Load More Quotes");
if(c.getCount()<15){
// Not Showing Load More Button
}
else {
list.addFooterView(btnLoadMore);}
list.setAdapter(adapter);
anifadein=AnimationUtils.loadAnimation(getApplicationContext(), R.anim.slidedown);
list.startAnimation(anifadein);
// Click event for single list row
list.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
map = quotesList.get(position);
Intent intent = new Intent(QuotesActivity.this,
QuoteDialogActivity.class);
int itemPosition = position;
if(startingPoint>=30){
intent.putExtra("Pos", itemPosition+1);
intent.putExtra("LstCount", list.getCount()-1);
}else{
intent.putExtra("Pos", itemPosition+1);
intent.putExtra("LstCount", list.getCount());}
intent.putExtra("QuoteId", map.get(KEY_ID));
intent.putExtra("quotesType", quType);
intent.putExtra("startFrom", getIntent().getStringExtra("startFrom"));
intent.putExtra("Quotes", quotesList);
// Log.i("COUNT",""+(itemPosition+1)+"-"+list.getCount());
intent.putExtra("Fav", map.get(KEY_FAVORITE));
startActivity(intent);
if (mInterstitial.isLoaded()) {
mInterstitial.show();
}
}
});
btnLoadMore.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
if(btnLoadMore.getVisibility()==View.VISIBLE){
Cursor newC = null;
if (quType != 0) {
switch (quType) {
case 1:
newC = db.getQuotes(""+startingPoint);
break;
case 2:
newC = db.getFavoriteQuotes(""+startingPoint);
//page.setVisibility(View.GONE);
break;
case 3:
newC = db.getAuthorQuotes(getIntent().getStringExtra("AuthorId"),""+startingPoint);
// page.setVisibility(View.GONE);
break;
}
}
// Starting a new async task
if(newC.getCount()<15){
btnLoadMore.setVisibility(View.INVISIBLE);
}
startingPoint+=15;
do{
map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put(KEY_ID, newC.getString(newC.getColumnIndex(KEY_ID)));
map.put(KEY_TEXT, newC.getString(newC.getColumnIndex(KEY_TEXT)));
map.put(KEY_AUTHOR, newC.getString(newC.getColumnIndex(KEY_AUTHOR)));
map.put(KEY_PICTURE, newC.getString(newC.getColumnIndex(KEY_PICTURE)));
map.put(KEY_PICTURE_SDCARD, String.valueOf(newC.getInt(newC
.getColumnIndex(KEY_PICTURE_SDCARD))));
map.put(KEY_WEB_ID,
String.valueOf(newC.getInt(newC.getColumnIndex(KEY_WEB_ID))));
//Log.i("web_id",String.valueOf(newC.getInt(newC.getColumnIndex(KEY_ID))));
map.put(KEY_FAVORITE, newC.getString(newC.getColumnIndex(KEY_FAVORITE)));
// adding HashList to ArrayList
quotesList.add(map);
if (mInterstitial.isLoaded()) {
mInterstitial.show();
}
} while (newC.moveToNext());
adapter.notifyDataSetChanged(); }}
});
}
}
I not sure from where Object "c" is coming but i m assuming it list object and getCount is return the current count of list. So, If you want to show "Show more" button when the size of list is greater than or equals to 15 then use this condition.
if(c.getCount() >= 15){
// Will show Load More Button
}
Put the Button in a layout XML File. Inflate it, then:
if (c.getCount() > 15) {
btnLoadMore.setVisibility(View.INVISIBLE);
}
If you want the Button to be invisible.

How to make an options menu for a PopupWindow?

My app has an options menu that is available in almost all Activities, which was created by implementing onCreateOptionsMenu(). But in one Activity there is a PopupWindow, and when this PopupWindow has focus (required for proper functioning) tapping the menu button does not bring up the options menu.
PopupWindows do not have an onCreateOptionsMenu() function. Is there some other way to add an options menu to a PopupWindow?
Alternatively, is there a way to get the options menu from the Activity behind it to show up when the user taps the menu button?
I solved this by intercepting the menu key and calling openOptionsMenu() on the activity. Here is the key listener:
OnKeyListener mMenuKeyListener = new OnKeyListener() {
#Override
public boolean onKey(View view, int keyCode, KeyEvent event) {
if(keyCode==KeyEvent.KEYCODE_MENU) {
activity.openOptionsMenu();
return true;
} else {
return false;
}
}
};
I think you have to add this key listener to every view in the PopupWindow to get it to work, so I wrote a function to do that:
public void setupMenuKeyListenerRecursive(View v) {
if (v != null) {
try {
ViewGroup viewGroup = (ViewGroup)v;
int childCount = viewGroup.getChildCount();
for (int index = 0; index < childCount; index++) {
View child = viewGroup.getChildAt(index);
setupMenuKeyListenerRecursive(child);
}
} catch (Exception e) {
}
v.setOnKeyListener(mMenuKeyListener);
}
}

get/use radio button value android

I FIGURED OUT WHAT I WAS DOING. I HAD THE VARIABLE NAME IN QUOTES WITH THE REST OF THE URL STRING.
How do you save the value of a Radio button into a variable and use that variable later.
I can see the variable Day_Item in my LogCat and the value is in there but when try using Day_Item later it does not show the valuable.
Below is a section of my code that shows the buttons.
String Day_Item = null;
public class SearchDB extends Activity {
private static final String TAG = "MyApp";
String start_log = "STARTED";
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.search_layout);
final RadioButton radio_monday = (RadioButton) findViewById(R.id.monday);
radio_monday.setOnClickListener(radio_listener);
cityspinner.setOnItemSelectedListener(new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position,long arg3)
{
int id = parent.getId();
if (spinner2_count2 < spinner2_count1 ) {
spinner2_count2++; }
else
{
String city_spinner_log = "CITY SPINNER";
Log.d(TAG, city_spinner_log);
String item = cityspinner.getSelectedItem().toString();
String nameContentType = "name";
String cityURL = "GetRestaurant.php?day=Day_Item&city=" + item;
Log.d(TAG, cityURL);
String shop_data = DataCall.getJSON(cityURL,nameContentType);
Log.d(TAG, shop_data);
Bundle bundle = new Bundle();
bundle.putString("shopData", shop_data);
Intent myIntent = new Intent(SearchDB.this, ShowRestaurant.class);
myIntent.putExtras(bundle);
startActivityForResult(myIntent, 0);
}
}
}
//ONCLICKLISTENER that saves RADIO value into a variable.
public OnClickListener radio_listener = new OnClickListener() {
public void onClick(View v) {
// Perform action on clicks
RadioButton rb = (RadioButton) v;
Day_Item = (String) rb.getText();
Log.d(TAG,Day_Item);
Toast.makeText(SearchDB.this, Day_Item, Toast.LENGTH_SHORT).show();
}
};
}
You would need a bit more code to get a good solid answer. Such as how is Day_Item allocated? And is it's scope global? Are you calling it from another activity or the one it's allocated within? These are just guesses at this point:
1) Are you sure your onClickListener isn't firing multiple times? Thus setting Day_Item to an undesired text or nothing at all?
2) Rather a question/answer,
"but when try using Day_Item later it does not show the valuable"
I'm assuming this means that it is null? Well if it's being set properly, and then it is being null'd... it either is being explicitly null'd by you somewhere (such as (1)) or else the allocation and scope are the issue area I believe...

Do you need to inflate a view in order to get its id for the onClick method?

Do you need to inflate a view in order to get its id for the onClick method? Because when I run my program in the emulator and click on the specific button it does nothing! I want it to go back to the main.xml layout! Do I need to procces the onClick some other way?
public void onClick(View v) {
switch( v.getId()){
case R.id.play:
setContentView(R.layout.play);
setQuestion();
break;
case R.id.level:
setContentView(R.layout.level);
if(lvl.equals("1")) {
lvl1.setChecked(true);
}
if(lvl.equals("2")) {
lvl2.setChecked(true);
}
if(lvl.equals("3")) {
lvl3.setChecked(true);
}
if(lvl.equals("4")) {
lvl4.setChecked(true);
}
if(lvl.equals("5")) {
lvl5.setChecked(true);
}
break;
case R.id.setLevel:
if(lvl1.isChecked()) {
setLevel("1");
}
if(lvl2.isChecked()) {
setLevel("2");
}
if(lvl3.isChecked()) {
setLevel("3");
}
if(lvl4.isChecked()) {
setLevel("4");
}
if(lvl5.isChecked()) {
setLevel("5");
}
setContentView(R.layout.main);
break;
}
}
Here is how I get the views:
setContentView(R.layout.main);
Button play = (Button)findViewById(R.id.play);
play.setOnClickListener(this);
Button level = (Button)findViewById(R.id.level);
level.setOnClickListener(this);
Button setLevel = (Button)getLayoutInflater().inflate(R.layout.level, null).findViewById(R.id.setLevel);
setLevel.setOnClickListener(this);
lvl1 = (RadioButton)getLayoutInflater().inflate(R.layout.level, null).findViewById(R.id.lvl1);
lvl2 = (RadioButton)getLayoutInflater().inflate(R.layout.level, null).findViewById(R.id.lvl2);
lvl3 = (RadioButton)getLayoutInflater().inflate(R.layout.level, null).findViewById(R.id.lvl3);
lvl4 = (RadioButton)getLayoutInflater().inflate(R.layout.level, null).findViewById(R.id.lvl4);
lvl5 = (RadioButton)getLayoutInflater().inflate(R.layout.level, null).findViewById(R.id.lvl5);
What should I do so that when I click the setLevel button it changes the view back to the main.xml view
Andrew,
You may want to make individual onClick() methods for each item. That's how I handle my click-able objects.
Example:
Button play = (Button)findViewById(R.id.play);
play.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
//perform play button actions here
}
});
This way you already have the button object created based on its ID value, and the onClickListener is specifically tailored to that item.
good luck!

Categories