Why does a button that is pressed, lose it's state when opening the options menu?
I made a sample activity to make it clear:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btn = (Button) findViewById(R.id.button1);
btn.setPressed(true); // set the state
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings)
return true;
return super.onOptionsItemSelected(item);
}
}
We set the button in our view to the pressed state.
When you run the project and then open the options menu, the pressed state is gone. It looks like the button has removed it's state.
What is the solution/workaround to keep the button state without redrawing the whole activity? Perhaps the implementation of a Button is not ment to have this behaviour and a toggle button needs to be used?
public class MainActivity extends Activity {
Button btn;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn; = (Button) findViewById(R.id.button1);
btn.setPressed(true); // set the state
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
//here you can set your state....
btn. //set the state...
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings)
return true;
return super.onOptionsItemSelected(item);
}
}
Related
I would like to create a logout alert dialog from my applications navigation drawer. All the other items in the nav drawer are fragments and I would like for this item to just show an alert dialog
Navigation Drawer
I previously had a button in my MainActivity that used an on click listener and firebase.getInstance.signOut() to take the user back to the login activity:
Previous button on click listener
//on click listener for logout
/*btnLogout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
FirebaseAuth.getInstance().signOut();
startActivity(new Intent(getApplicationContext(),LoginActivity.class));
finish();
}
});*/
After some redesign I created a navigation drawer that utilizes fragments and i would like when the user selects logout to be prompted with an alert dialog asking are they sure , then for the button to act just how my previous one did and send the user back to the login activity.
I dont see the need of creating another fragment to logout but, correct me if I'm wrong.
Mainactivity.java
public class MainActivity extends AppCompatActivity implements NavigationView.
OnNavigationItemSelectedListener,MainFragment.onFragmentBtnSelected{
public TextView verifyMsg;
public Button btnLogout, verifyEmailBtn;
FirebaseAuth fauth;
public DrawerLayout drawerLayout;
public ActionBarDrawerToggle actionBarDrawerToggle;
public NavigationView navigationView;
AlertDialog.Builder reset_alert;
LayoutInflater inflater;
FragmentManager fragmentManager;
FragmentTransaction fragmentTransaction;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//xml map to java
//btnLogout = findViewById(R.id.btnLogout);
verifyMsg = findViewById(R.id.verifyEmailMsg);
verifyEmailBtn = findViewById(R.id.btnVerifyEmail);
fauth = FirebaseAuth.getInstance();
reset_alert = new AlertDialog.Builder(this);
inflater =this.getLayoutInflater();
//new stuff
androidx.appcompat.widget.Toolbar toolbar = findViewById(R.id.toolbar2);
setSupportActionBar(toolbar);
drawerLayout = findViewById(R.id.drawer);
navigationView = findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
actionBarDrawerToggle = new
ActionBarDrawerToggle(this, drawerLayout,
toolbar, R.string.nav_open, R.string.nav_close);
drawerLayout.addDrawerListener(actionBarDrawerToggle);
actionBarDrawerToggle.setDrawerIndicatorEnabled(true);
actionBarDrawerToggle.syncState();
//fragment manager - creates instance of a fragment
//load default fragment
fragmentManager = getSupportFragmentManager();
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.container_fragment,new MainFragment());
fragmentTransaction.commit();
//if the user email is not verified still show verify msg
if(!fauth.getCurrentUser().isEmailVerified()){
verifyEmailBtn.setVisibility(View.VISIBLE);
verifyMsg.setVisibility(View.VISIBLE);
}
//on click listener for verify email button
verifyEmailBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//send verification email
fauth.getCurrentUser().sendEmailVerification()
.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Toast.makeText(MainActivity.this,"Verification Sent",Toast.LENGTH_SHORT).show();
verifyEmailBtn.setVisibility(View.GONE);
verifyMsg.setVisibility(View.GONE);
}
});
}
});
}
//able to select the items in nav drawer
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
//auto close drawer
drawerLayout.closeDrawer(GravityCompat.START);
//Fragment fragment;
int mId = item.getItemId();
}
if (mId == R.id.homeItem){
//load default fragment
fragmentManager = getSupportFragmentManager();
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.container_fragment,new MainFragment());
fragmentTransaction.commit();
}
if (mId == R.id.profileSettings){
fragmentManager = getSupportFragmentManager();
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.container_fragment,new ProfileFragment());
fragmentTransaction.commit();
}
if (mId == R.id.logoutItem){
}
return true;
}
#Override
public void onBtnSelected() {
fragmentManager = getSupportFragmentManager();
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.container_fragment,new ProfileFragment());
fragmentTransaction.commit();
} }
MainFragment.java
public class MainFragment extends Fragment {
private onFragmentBtnSelected listener;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container,
#Nullable Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.fragment_main,container,false);
Button clickme = view.findViewById(R.id.clickHF);
clickme.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
listener.onBtnSelected();
}
});
return view;
}
#Override
public void onAttach(#NonNull Context context){
super.onAttach(context);
if(context instanceof onFragmentBtnSelected ){
listener =(onFragmentBtnSelected) context;
}
else {
throw new ClassCastException(context.toString() + " must implement listiner");
}
}
public interface onFragmentBtnSelected{
public void onBtnSelected();
}
}
nav_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<item android:title="General">
<menu>
<item
android:id="#+id/homeItem"
android:icon="#drawable/ic_baseline_home_24"
android:title="#string/Home" />
</menu>
</item>
<item android:title="Account Settings">
<menu>
<item
android:id="#+id/profileSettings"
android:icon="#drawable/ic_baseline_account_circle_24"
android:title="Profile" />
</menu>
</item>
<item android:title="App Features">
<menu>
<item
android:id="#+id/logoutItem"
android:icon="#drawable/ic_baseline_power_settings_new_24"
android:title="#string/logout" />
</menu>
</item></menu>
Any help would be greatly appreatiated , having trouble best utilizing fragments in a navigation drawer
Mainactivity.java:
onNavigationItemSelected method inside this
without Alert Dialog
if (mId == R.id.logoutItem){
FirebaseAuth.getInstance().signOut();
startActivity(new Intent(getApplicationContext(),LoginActivity.class));
finish();
}
with Alert Dialog use
if (mId == R.id.logoutItem){
MaterialAlertDialogBuilder(this)
.setTitle("Title")
.setMessage("Message")
.setIcon(android.R.drawable.ic_dialog_alert)
.setPositiveButton("Ok") { _, _ ->
FirebaseAuth.getInstance().signOut();
startActivity(new
Intent(getApplicationContext(),LoginActivity.class));
finish();
}
.setNegativeButton("Cancel") { _, _ ->
Toast.makeText(this, "clicked Cancel", Toast.LENGTH_LONG).show()
}
.show()
}
Hell o,
I would like to know if it's preferrable to inflate a fragment extending DialogFragment class or to display the dialog from a simple method added in onCreateView() ?
Here's a snippet for the second solution from internet (based on an activity and not fragment) :
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
positiveDialog = findViewById(R.id.btnPositiveDialog);
negativeDialog = findViewById(R.id.btnNegativeDialog);
positiveDialog.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
showAlertDialog(R.layout.dialog_postive_layout);
}
});
negativeDialog.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
showAlertDialog(R.layout.dialog_negative_layout);
}
});
}
private void showAlertDialog(int layout){
dialogBuilder = new AlertDialog.Builder(MainActivity.this);
View layoutView = getLayoutInflater().inflate(layout, null);
Button dialogButton = layoutView.findViewById(R.id.btnDialog);
dialogBuilder.setView(layoutView);
alertDialog = dialogBuilder.create();
alertDialog.getWindow().getAttributes().windowAnimations = R.style.DialogAnimation;
alertDialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
alertDialog.show();
dialogButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
alertDialog.dismiss();
}
});
}
}
My only concern is that i use a fragment among navigationDrawer where i want to display my alertDialog (1 editText and 2 buttons), and i would like to prevent user from closing the dialog via backbutton or clicking outside the dialog.
Thank you very much for helping me out
Hey guys I have a recyclerview adapter that populates list of some data on a cardview. I created a three dot menu towards the lower right bottom of the card layout which would actually delete the card row from the recyclerview and also make delete of the item from the sqlite database that stores rows data. The issue is I couldn't figure out how to integrate the method that would implement the delete into the recyclerview ViewHolder. Here is the source code
public class BeneficiaryRecyclerAdapter extends RecyclerView.Adapter<BeneficiaryRecyclerAdapter.BeneficiaryViewHolder> {
private List<Beneficiary> listBeneficiary;
public ImageView overflow;
private Context mContext;
public BeneficiaryRecyclerAdapter(){
}
public BeneficiaryRecyclerAdapter(List<Beneficiary> listBeneficiary, Context mContext) {
this.listBeneficiary = listBeneficiary;
this.mContext = mContext;
}
#Override
public BeneficiaryViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// inflating recycler item view
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_beneficiary_recycler, parent, false);
return new BeneficiaryViewHolder(itemView);
}
#Override
public void onBindViewHolder(final BeneficiaryViewHolder holder, int position) {
holder.textViewName.setText(listBeneficiary.get(position).getName());
holder.textViewEmail.setText(listBeneficiary.get(position).getEmail());
holder.textViewAddress.setText(listBeneficiary.get(position).getAddress());
holder.textViewCountry.setText(listBeneficiary.get(position).getAddress());
holder.overflow.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
showPopupMenu(holder.overflow);
}
});
}
/**
* Showing popup menu when tapping on 3 dots
*/
private void showPopupMenu(View view) {
// inflate menu
PopupMenu popup = new PopupMenu(this.mContext, view);
MenuInflater inflater = popup.getMenuInflater();
inflater.inflate(R.menu.beneficiary_m, popup.getMenu());
popup.setOnMenuItemClickListener(new MyMenuItemClickListener());
popup.show();
}
//NOTE: The method that would delete the item from the database and recyclerview but i need this method to be called from the onMenuItemClick of the case with id of case R.id.action_delete_beneficiary
public void deleteItem(final BeneficiaryViewHolder holder, int position) {
final DatabaseHelper2 db = new DatabaseHelper2(mContext);
db.open();
db.deleteContact(position);
db.close();
listBeneficiary.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, listBeneficiary.size());
holder.itemView.setVisibility(View.GONE);
}
/**
* Click listener for popup menu items
*/
class MyMenuItemClickListener implements PopupMenu.OnMenuItemClickListener {
public MyMenuItemClickListener() {
}
#Override
public boolean onMenuItemClick(MenuItem menuItem) {
switch (menuItem.getItemId()) {
case R.id.action_delete_beneficiary:
Toast.makeText(mContext, "deleting beneficiary", Toast.LENGTH_SHORT).show();
return true;
case R.id.action_edit_beneficiary:
Toast.makeText(mContext, "editing beneficiary", Toast.LENGTH_SHORT).show();
return true;
default:
}
return false;
}
}
#Override
public int getItemCount() {
Log.v(BeneficiaryRecyclerAdapter.class.getSimpleName(),""+listBeneficiary.size());
return listBeneficiary.size();
}
/**
* ViewHolder class
*/
public class BeneficiaryViewHolder extends RecyclerView.ViewHolder {
public AppCompatTextView textViewName;
public AppCompatTextView textViewEmail;
public AppCompatTextView textViewAddress;
public AppCompatTextView textViewCountry;
public ImageView overflow;
public BeneficiaryViewHolder(View view) {
super(view);
textViewName = (AppCompatTextView) view.findViewById(R.id.textViewName);
textViewEmail = (AppCompatTextView) view.findViewById(R.id.textViewEmail);
textViewAddress = (AppCompatTextView) view.findViewById(R.id.textViewAddress);
textViewCountry = (AppCompatTextView) view.findViewById(R.id.textViewCountry);
overflow = (ImageView) view.findViewById(R.id.overflow);
}
}
}
I would be glad if anybody can help me with this.
Use this code to delete recyclerview items on same row click button.
holder.deleteImg.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(list.size()!=0){
list.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position,list.size());
}
}
});
viewPager4 Fragment Activities
If I click on the Texts that play short sounds, one after another then after sometimes the mediaplayer hangs and doesn't play any sound. But if I'm able to destroy activity and recreate the same activity with refresh button in Action Bar, I'd be able to click sounds again.
So what to write in the code for R.id.item2?
Or there is any other way that continuous clicking on short sounds by these texts is possible without any hang kind of problem?
Following is the reference code:
public class module1 extends FragmentActivity {
static Context con;
static int length = 0;
ViewPager mViewPager;
SectionsPagerAdapter mSectionsPagerAdapter;
static MediaPlayer mediaplayer, mediaplayert, m;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
con = this;
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.mains, menu);
// Just .main into .mains [created new for different behavior of Action Bar]
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.item1) {
Intent in = new Intent(Intent.ACTION_VIEW,
Uri.parse("http://www.google.com"));
startActivity(in);
}
if (item.getItemId() == R.id.item2) {
//what should i write here? to destroy and recreate the same fragment activity again.
//Problem: After clicking fast on one after another text links, mediaplayert hangs and doesnt play
//Solution: exit app destroy and reopen, then mediaplayer works fine...
//SO, what to write here? kindly help!
}
return super.onOptionsItemSelected(item);
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int arg0) {
Fragment ff = new DummySectionFragment1();
switch (arg0) {
case 0:
ff = new DummySectionFragment1();
break;
}
Bundle args = new Bundle();
args.putInt(DummySectionFragment1.ARG_SECTION_NUMBER, arg0 + 1);
ff.setArguments(args);
return ff;
}
#Override
public int getCount() {
return 1;
}
#Override
public CharSequence getPageTitle(int arg0) {
Locale l = Locale.getDefault();
switch (arg0) {
case 0:
return getString(R.string.title_section27).toUpperCase(l);
}
return null;
}
}
public static class DummySectionFragment1 extends Fragment {
public static final String ARG_SECTION_NUMBER = "section_number";
public DummySectionFragment1() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.m01set01, container, false);
// Genius Shot by Stupid vIC//
TextView Text = (TextView) rootView.findViewById(R.id.textView2);
Text.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
mediaplayert = MediaPlayer.create(MainActivity.con,
R.raw.sound1);
mediaplayert.start();
}
});
TextView Text1 = (TextView) rootView.findViewById(R.id.textView4);
Text1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
mediaplayert = MediaPlayer.create(MainActivity.con,
R.raw.sound2);
mediaplayert.start();
}
});
TextView Text2 = (TextView) rootView.findViewById(R.id.textView6);
Text2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
mediaplayert = MediaPlayer.create(MainActivity.con,
R.raw.sound3);
mediaplayert.start();
}
});
return rootView;
}
}
#Override
protected void onDestroy() {
if (mediaplayert != null) {
mediaplayert.stop();
mediaplayert= null;
}
super.onDestroy();
}
}
In my android application, I am switching between the two set of images-(Set1, Set2) displayed in a GridView-A inside a Fragment-A.I am doing this on a button press using a boolean variable. Clicking on any GridView icon leads to another Fragment-B. The problem is when I press back button on Fragment-B , the Fragment-A is always loaded with the images of Set1 by default. I want the same set of images (Set1 or Set2 ) to be loaded on FramentA that were displayed before going to FragmentB.
EDITED:
Fragment Code
public class GridViewFragment extends Fragment {
Context context;
GridView GridMenu;
GridViewAdapter ga;
Button Btn_Settings;
Button Btn_lang_Ch;
Button favoriteDuas;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//fragment = new GridViewFragment();
if (view == null) {
context = inflater.getContext();
view = inflater.inflate(R.layout.fragment_gridview, container, false);
ga = new GridViewAdapter(context);
Btn_lang_Ch = (Button) view.findViewById(R.id.lng_ch);
Btn_Settings = (Button) view.findViewById(R.id.button_settings);
favoriteDuas = (Button) view.findViewById(R.id.btn_favorite_duas);
GridMenu = (GridView) view.findViewById(R.id.gridView1);
GridMenu.setAdapter(ga);
} else {
// remove view from previously attached ViewGroup
ViewGroup parent = (ViewGroup) view.getParent();
parent.removeView(view);
}
return view;
}
#Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
Btn_lang_Ch.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
ga.changeImages(!ga.imageSetChange);
ga.Lang_Status();
}
});
GridMenu.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View view, int position, long id) {
((MainActivity) context).loadSingleDuaFragment();
}
});
super.onActivityCreated(savedInstanceState);
}
}
GridView Adapter
public class GridViewAdapter extends BaseAdapter {
public boolean imageSetChange = false;
public static boolean curr_lang = false;//english
public Integer[] mThumbIds = {
R.drawable.eng_pic1, R.drawable.eng_pic2,
R.drawable.eng_pic3, R.drawable.eng_pic4,
R.drawable.eng_pic5, R.drawable.eng_pic6,
R.drawable.eng_pic7, R.drawable.eng_pic8,
R.drawable.eng_pic9, R.drawable.eng_pic10,
R.drawable.eng_pic11, R.drawable.eng_pic12,
R.drawable.eng_pic13, R.drawable.eng_pic14,
R.drawable.eng_pic15, R.drawable.eng_pic16,
R.drawable.eng_pic17, R.drawable.eng_pic18,
R.drawable.eng_pic19, R.drawable.eng_pic20,
R.drawable.eng_pic21
};
public Integer[] mThumbIds1 = {
R.drawable.urdu_dua1, R.drawable.urdu_dua2,
R.drawable.urdu_dua3, R.drawable.urdu_dua4,
R.drawable.urdu_dua5, R.drawable.urdu_dua6,
R.drawable.urdu_dua7, R.drawable.urdu_dua8,
R.drawable.urdu_dua9, R.drawable.urdu_dua10,
R.drawable.urdu_dua11, R.drawable.urdu_dua12,
R.drawable.urdu_dua13, R.drawable.urdu_dua14,
R.drawable.urdu_dua15, R.drawable.urdu_dua16,
R.drawable.urdu_dua17, R.drawable.urdu_dua18,
R.drawable.urdu_dua19, R.drawable.urdu_dua20,
R.drawable.urdu_dua21
};
private Context mContext;
public GridViewAdapter(Context c) {
mContext = c;
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return mThumbIds.length;
}
#Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return mThumbIds[position];
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View MyView;
if (convertView == null) {
LayoutInflater li = ((Activity) mContext).getLayoutInflater();
MyView = li.inflate(R.layout.menuitem, parent, false);
} else {
MyView = (View) convertView;
}
ImageView iv = (ImageView) MyView.findViewById(R.id.image);
if (imageSetChange) {
iv.setImageResource(mThumbIds1[position]);
} else {
iv.setImageResource(mThumbIds[position]);
}
return MyView;
}
public void changeImages(boolean change) {
this.imageSetChange = change;
notifyDataSetChanged();
// gf.Lang_Status();
}
public void Lang_Status() {
// if curr_eng
if (!curr_lang)
this.curr_lang = true; // change to urdu
// if curr_urdu
else
this.curr_lang = false; // change to english
}
}
EDIT:
MainActivity
public void loadGridViewFragment() {
if (activityActive) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
if(getSupportFragmentManager().findFragmentByTag(GridViewFragment.TAG)!=null){
ft.replace(R.id.fl_view, frag,GridViewFragment.TAG);
}
else
{
frag = new GridViewFragment();
ft.replace(R.id.fl_view, frag,GridViewFragment.TAG);
}
ft.commit();
}
}
So, can anybody help me out regarding what should be done to load the previous set of images on coming back to gridview fragment instead of having the default images of Set1.