How to properly apply and customize a global navigation drawer with Activities - java

I am working on a big app that has recently adapted the drawer navigation style and now I'm trying to customize some of the elements.
Because of its great size and complexity it was decided to adapt the navigation drawer to Activities and Fragment Activites instead of Fragments as the extended standard use.
For that I created a base Drawer activity called NavDrawer, which is inherited/extended by all of those activities that need to navigate with the Drawer. Every Activity that extends NavDrawer Activity calls NavDrawer onCreate method by calling super.onCreate(savedInstanceState, R.activity_layout) adding its layout_id instead of executing setContentView(R.layout_id).
This base Activity also handles all the intent calls to the other different activities whenever the user clicks on one of the sections/textviews.
I managed to make it work pretty well so far but I'm facing now a weird issue when customizing the Typeface of the TextViews inside the drawer. First time it is launched the app, I can see all the links without the proper style, but only after selecting one of the sections of the drawer, navigating to it and opening again the drawer, I see the textviews properly formated with my custom font.
I have been struggling with it for a few days already, and I am sure it has to be a stupid rookie mistake but I can´t figure it out what it is.
This is the NavDrawer class OnCreate method:
protected void onCreate(Bundle savedInstanceState, int resLayoutID) {
super.onCreate(savedInstanceState);
setContentView(resLayoutID);
AC = (ApplicationController)getApplicationContext();
mModel = AC.getModel();
//Setting up controls for the navigation drawer
if(AC.getModel().hasRatedApp() != null && AC.getModel().hasRatedApp()){
mLinksTitles = getResources().getStringArray(R.array.menu_links_has_rated);
}
else
mLinksTitles = getResources().getStringArray(R.array.menu_links_has_not_rated);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerContainer = (LinearLayout) findViewById(R.id.left_drawer_cont);
mDrawerList = (ListView) findViewById(R.id.menu_links);
// set a custom shadow that overlays the main content when the drawer opens
mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
// set up the drawer's list view with items and click listener
mDrawerList.setAdapter(new ArrayAdapter<String>(AC, R.layout.drawer_list_item, mLinksTitles){
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
Typeface mFaceR = Typeface.createFromAsset(getApplicationContext().getAssets(), "fonts/Lato-Regular.ttf");
View v = super.getView(position, convertView, parent);
((TextView) v).setTypeface(Typeface.createFromAsset(getApplicationContext().getAssets(), "fonts/Lato-Light.ttf"));
return v;
}
});
I would really appreciate any help or code you could provide me since I´m still quite new in Android development.

Finally I just found out what was going on, actually I set by mistake another adapter for my mDrawerList later in the code. As I said, stupid rookie mistake, but the code above still worked for me and hope it can help other people to customize their Navigation Drawers too.

Related

OnBackPressed for each item in the NavigatorView

There is a NavigatorView in which I am using the NavController. The whole problem is that when replacing the Fragmenta, I immediately set fragmentTransaction.addToBackStack (String.valueOf (FragmentRink3)); and when navigating to another NavController when clicking on OnBackPressed, is applied to the fragment from the previous NavController where the replacement was made. It's hard to explain. Is it possible to somehow do so that each of the lower navigation menu has its own, I don’t know, a list of clicks, according to which the sequence of transitions to fragments was determined? I know I explained very poorly, I will attach a gif to show the problem clearly.
As you can see, by clicking on the button, the fragment was replaced, then I went to the next menu and clicked OnBackPressed, and at this moment the fragment, which was replaced in the previous menu, went back. How to fix it?
I will replace the fragment as follows:
btn_close.setOnClickListener(v ->
{
FragmentRink4 fragment = new FragmentRink4(); // you fragment
FragmentManager fragmentManager = ((FragmentActivity) v.getContext()).getSupportFragmentManager(); // instantiate your view context
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.nav_controller_rink1, fragment);// your container and your fragment
fragmentTransaction.addToBackStack(String.valueOf(FragmentRink3));
fragmentTransaction.commit();
});
Here is a link to the project.

Error inflating class fragment. What can I do here?

I was coding this program the other day, hoping that the fragment was doing okay, but it isn't. My project is a Relative Layout app where the GPS map will show up on the screen first thing the activity pops up, and then the choices to view some of the Javanese culture of Indonesia (in the form of Grid - Card View combination), will be available for selection.
Here, in this line, I have a class fragment inflation error, according to Logcat :
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_java_island); // Erroring line
KerisCard = (CardView) findViewById(R.id.KerisCard);
TradClothesCard = (CardView) findViewById(R.id.TradClothesCard);
TradHouseCard = (CardView) findViewById(R.id.TradHouseCard);
TariMerakCard = (CardView) findViewById(R.id.TariMerakCard);
SupportMapFragment javaMapFragment = (SupportMapFragment) getSupportFragmentManager().
findFragmentById(R.id.java_island_map);
javaMapFragment.getMapAsync(this); . . . }
In retrospect, I'm not very familiar to the concept of fragments as the classes I've been attending aren't going too detailed on the usage of fragments. Also, I have to note without the declaring the object references ((CardView) declarations on the onCreate() function), this error would not show up, and the app will be executable as normal.
Instead of making support fragment reference create fragment reference directly and call method from fragment.
SampleFragment fragment=new SampleFragment()
Fragment .someMethod
Here is a confusion
Do you want to open fragment in activity ?
Because you are trying to find fragment from id ,so have you created in xml if not then there is problem.

Implement bottom drawer in android Java

I am unable to implement a bottom drawer in android (java) and can not find any working example/tutorial on its usage. Can you write sample code for using a bottom drawer? (https://material.io/components/navigation-drawer/#bottom-drawer)
Alternatively, I tried using a drop down menu but my app needs a bottom drawer only
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/navbottom"
android:layout_width="match_parent"
android:layout_height="64dp"
android:layout_gravity="bottom"
app:menu="#menu/menu_nav"> </com.google.android.material.bottomnavigation.BottomNavigationView>```
Here's the code to my bottom navigation view
This is how it should look like1
In the screenshot that you added, I saw something that looks like BottomSheet. To get this look of dialog you probably want to use BottomSheetDialogFragment so below I will explain how to implement it inside your Activity.
1) First of all, you need to create a class that will extend from BottomSheetDialogFragment and inflate the layout that will be used by this fragment.
public class ExampleBottomSheetDialog extends BottomSheetDialogFragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle
savedInstanceState) {
return inflater.inflate(*R.layout.bottom_sheet_layout*, container, false);
}
}
2) Then you need to create the *R.layout.bottom_sheet_layout* layout file that will hold needed views and provide logic for them if it's needed.
3) After that, you can programmatically set Dialog logic. So for example, you could open this dialog by pressing the button.
Button buttonDialogBottomSheet = findViewById(R.id.btn_sh_dialog);
buttonDialogBottomSheet.setOnClickListener((v) -> {
ExampleBottomSheetDialog bottomSheetDialog = new ExampleBottomSheetDialog();
bottomSheetDialog.show(getSupportFragmentManager(), "simple tag");
});
If you're looking for standard Bottom Sheet just let me know, I will update the answer.
Result of code written above:
link

Android - setVisibility not changing visibility of RelativeLayout

I am trying to manipulate the visibility of RelativeLayout on a certain click event, using the visibility attribute.
After adding event handlers to each list item, I can check that the visibility status is changing, but in the Android emulator, the screen doesn't change at all (and I have tested it with visibility="visible" in the XML to make sure that it would show up).
Here's the code for the click handler:
someHolder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
LayoutInflater layoutSeed = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View baseView = layoutSeed.inflate(R.layout.activity_listings, null, false);
RelativeLayout popup = (RelativeLayout) baseView.findViewById(R.id.popupContainer);
Log.d("Tag1",Integer.toString(popup.getVisibility()));
popup.setVisibility(View.VISIBLE);
Log.d("Tag2",Integer.toString(popup.getVisibility()));
}
});
Logcat shows the status change. I've also tried to invalidate() and postInvalidate() on both baseView and popup, as well as popup.bringToFront() and the combinations of these and so far nothing's working.
Any suggestions or possible routes to investigate?
If the RelativeLayout you are trying to change visibility is already in the screen, you don't need to inflate it again. Please make a reference to already inflated one and change its visibility
holder.relativeLayout.setVisibility(View.GONE);
Gone will remove the view from your layout. Use Invisible instead of gone.
when you click on button your View is replace by button's OnClick(View v) method.
so you just write down
v.popup(View.GONE)
Look at this line of code:
View baseView = layoutSeed.inflate(R.layout.activity_listings, null, false);
RelativeLayout popup = (RelativeLayout) baseView.findViewById(R.id.popupContainer);
Log.d("Tag1",Integer.toString(popup.getVisibility()));
Actually, you're trying to create a new baseView and set it gone. If you want to set the row item gone, you should remove it from your adapter temporary instead such as (if you set itemView to gone, you should be careful with the resuing view of the adapter):
removeItemAt(getAdapterPosition())
notifyDataRemoved(getAdapterPosition())

Android: Best way to retain listview content in fragment in tabbed app?

Firstly, this is my first question on StackOverflow so please forgive any formatting issues etc.
I'm writing an Android tablet application which allows users to populate a ListView with content pulled from a web service. At the minute there is one activity which contains a ViewPager which contains 6 fragments on different pages.
The issue is that the data which is downloaded and added to the ListView disappears when the user changes to another tab/back again and the Fragment's OnCreateView method is called (which initialises the ListView back to empty)
What's the best way of keeping the content of the listview besides storing it in a database/sharedprefs. The data in the listview needs to be destroyed when the user logs out/restarts the application, so I'm hoping to not persist it in any way.
the OnCreateView of the ListView container fragment:
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_certificate_list, container, false);
return rootView;
}
And here's the code which populates the ListView when the user hits the download button:
ListView lv = (ListView) callerActivity.findViewById(R.id.listView1);
lv.setAdapter(new CertListAdapter(callerActivity.getBaseContext(), activeCerts));
if (activeCerts.size() > 0) {
((TextView) callerActivity.findViewById(R.id.certStatusLabel)).setVisibility(View.GONE);
} else {
((TextView) callerActivity.findViewById(R.id.certStatusLabel)).setText(callerActivity.getString(R.string.certsDontExist));
}
the activeCerts variable is an arraylist of certificate objects which are obtained from the web service.
EDIT
Found a solution for this, to simply check if the "activeCerts" variable is null in the onCreateView method and populate the ListView again if it's not null. When the user logs out I'll just set activeCerts to null.
Cheers
"Correct" way:
use Fragment.onSaveInstanceState(Bundle) and Fragment.onActivityCreated(Bundle) to save and restore your items
Cheap way:
set android:configChanges="orientation|keyboardHidden|screenSize" on your activity hosting the fragment
You can also setRetainInstance(true); in the onCreate() of your Fragment
Read more about all this here.

Categories