Icon not showing in FloatingActionButton after changed programmatically - android

I have an AppCompatActivity with a TabLayout and a FloatingActionButton that I change it's icons depending on which tab is currently displaying.
When I programmatically change the drawable of FloatingActionButton using setImageDrawable or setImageResource, the new icon does not show up, just the blank background of the button.
Strangely enough, if I hide and show the FloatingActionButton after I programmatically changed it's icon, it shows up.
This is the part where I change the icon:
mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout) {
#Override
public void onPageSelected(int position) {
super.onPageSelected(position);
switch (position) {
case 0:
floatingActionButton.setImageDrawable(ContextCompat.getDrawable(mMainActivity, R.drawable.ic_save_24dp));
if (!floatingActionButton.isShown()) floatingActionButton.show();
mNavigationView.getMenu().getItem(1).setChecked(true);
break;
case 1:
floatingActionButton.setImageDrawable(ContextCompat.getDrawable(mMainActivity, R.drawable.ic_add_24dp));
if (!floatingActionButton.isShown()) floatingActionButton.show();
mNavigationView.getMenu().getItem(2).setChecked(true);
break;
case 2:
floatingActionButton.hide();
mNavigationView.getMenu().getItem(3).setChecked(true);
break;
}
}
});
Before:
After I programmatically changed it to a "plus" vector drawable:
Expected:
So, my question is: What is causing this, and how can it be solved?

I also had this problem and I solved by adding a call to the hide method
mFloatingActionButton.setImageDrawable(getDrawable(R.drawable.default_fab_icon));
mFloatingActionButton.hide();
mFloatingActionButton.show();
I had tried .invalidate() but that did not work. This seems to be a problem when switching fragments. I experienced it whilst using the Navigation AndroidX components.
I don't think this is the best solution but I tried a lot and only this worked - there's no flickering effect.

It is a known bug: https://issuetracker.google.com/issues/117476935
Just upgrade to com.google.android.material:material:1.1.0-beta02 which fixes this issue.

Related

Block scroll along with Expand/Collapse Collapsible Toolbar

I was using Collapsible Toolbar in my app. On activity launch Collapsible Toolbar is expanded state with scrolling enabled and its working well normally. But now I have a requirement to show a full screen error layout in case my API fails. In that case I have to collapsed toolbar with scrolling effect blocked.
Error Layout shows a Retry Button. On Retry I make API call again and if API gives success I have to again expand Toolbar and enable scrolling effect.
I was able to collapse toolbar with setExpanded(flag, animate) but in that case I am not able to block scrolling effect of Collapsible Toolbar while error layout is shown.
I need to provide a way to block as well as unblock scroll effect + Expand/Collapse Toolbar. Any help would be really appreciated.. !!!
Make your error layout such that it will overlap Collapsible Toolbar. Also set android:clickable="true" to your error layout.
When you set visibility to your error layout, set Toolbar scrolling accordingly.
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#f3f3f3"
android:orientation="vertical"
>
<!-- Add your other layout including Collapsible Toolbar here.-->
<RelativeLayout
android:id="#+id/errorLayout"
android:clickable="true"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</RelativeLayout>
I created a library AppBarrr to lock the screen in expanded mode, based on my previous answer.
As I said, the height of the Toolbar is the key: the CollapsingToolbarLayout will collapse until the Toolbar's height and will expand until the AppBarLayout's height.
With this library, you must set two layouts as the Toolbar and your Expanded Layout (used to lock the screen and the scroll), it will create a CollapsingToolbarLayout and inflate these layouts inside.
You can declare the animations duration, the color of the inner CollapsingToolbarLayout, the collapsed/expanded title's style, even the height of the locked layout... You could also hide the Expanded Layout if you click outside it. It can support NestedScrollView and ScrollView inside the Expanded Layout. The documentation and a sample app are available on Github.
For those who don't want to use the library, my previous answer shows the way to do it. Here's the output of the previous answer:
Basically, this is the same concept, but no need to write a full class, with the lib you just need to have a simple widget in xml and that's it!
Feel free to use, fork or test. Hope it will be useful ;)
If you use AlertDialog to communicate the error and a ProgressDialog (spinner) to show you are doing stuff, you can block user input while your app is doing it's thing.
A simple solution that you can apply is just use the property
android:visibility="gone"
for the content that you don't want to show and just make your error layout visible by using property android:visibility="visible"
place the error layout at the bottom of your parent layout
once the contents are not visible on screen and error layout is just visible you will achieve the desired result that you want. Hope this helps you.
You can implement the interface and call its methods when to enable or disable the collapsing effect.
public interface AppbarRequestListener {
void unlockAppBarOpen();
void lockAppBarClosed();
}
#Override
public void unlockAppBarOpen() {
appBarLayout.setExpanded(true, false);
appBarLayout.setActivated(true);
setAppBarDragging(false);
}
#Override
public void lockAppBarClosed() {
appBarLayout.setExpanded(false, false);
appBarLayout.setActivated(false);
setAppBarDragging(false);
}
private void setAppBarDragging(final boolean isEnabled) {
CoordinatorLayout.LayoutParams params =
(CoordinatorLayout.LayoutParams) appBarLayout.getLayoutParams();
AppBarLayout.Behavior behavior = new AppBarLayout.Behavior();
behavior.setDragCallback(new AppBarLayout.Behavior.DragCallback() {
#Override
public boolean canDrag(AppBarLayout appBarLayout) {
return isEnabled;
}
});
params.setBehavior(behavior);
}

Changing background colour for the Selected Tab

This is my Screen layout, and i want to do this, when I clicked on Popular tab, then Popular block should turns Blue.
Same for the Price, Time and Duration tab.
I've tried to do with Linear Layout but it doesn't.
i have taken it in Text View, and the vertical and Horizontal Lines are used using View tag and I have not use TabLayout, just to make it simple I just used TextView With Background.
Please suggest me a proper solution with code if you can.
Any help would be Appreciated.
In your xml file add following line in your TabLayout,
app:tabBackground="#0000FA"
by this you can chage color of selected tab.
If you have used TextView then just simply create or add this method to you java file & call it from each textviews onclick event by passing the textview to it.
public void changeTabColor(TextView tvSelected){
tv1.setBackgroundColor(Color.White);
tv2.setBackgroundColor(Color.White);
tv3.setBackgroundColor(Color.White);
tvSelected.setBackgroundColor(Color.Blue);
}
try this :
public void onClick(View v) {
switch (v.getId()) {
case R.id.popular_tab:
ResetTabColor();
popular_tab.setBackgroundColor(Color.blue);
case //Do the rest with other tab
}
}
private void ResetTabColor(){
popular_tab.setBackgroundColor(Color.TRANSPARENT); // or white color
time_tab.setBackgroundColor(Color.TRANSPARENT);
duration_tab.setBackgroundColor(Color.TRANSPARENT);
price_tab.setBackgroundColor(Color.TRANSPARENT);

Textview with background color

I am new to android. I got stuck while doing an application.I have taken 5 textviews with time slots,I would like to show that when I click one text view it should change its background color and when I click another textview the first text view's background color has to disappear and present text view's color has to be highlight.
Here I am posting my code:
public void onClick(View v) {
switch (v.getId()){
case R.id.time_slot_one:
setTimeSlotOne.setBackgroundColor(Color.parseColor("#bdbdbd"));
break;
case R.id.time_slot_two:
setTimeSlotTwo.setBackgroundColor(Color.parseColor("#bdbdbd"));
break;
case R.id.time_slot_three:
setTimeSlotThree.setBackgroundColor(Color.parseColor("#bdbdbd"));
break;
case R.id.time_slot_four:
setTimeSlotFour.setBackgroundColor(Color.parseColor("#bdbdbd"));
break;
case R.id.time_slot_five:
setTimeSlotFive.setBackgroundColor(Color.parseColor("#bdbdbd"));
break;
}
A simple way would be to create a disable Background function that will be called each time you click a new one.
public void removeBackgroundColors() {
setTimeSlotOne.setBackgroundColor(Color.WHITE);
setTimeSlotTwo.setBackgroundColor(Color.WHITE);
setTimeSlotThree.setBackgroundColor(Color.WHITE);
setTimeSlotFour.setBackgroundColor(Color.WHITE);
setTimeSlotFive.setBackgroundColor(Color.WHITE);
}
now simply change your code to:
case R.id.time_slot_two:
removeBackgroundColors();
setTimeSlotTwo.setBackgroundColor(Color.parseColor("#bdbdbd"));
break;
...
Even simpler is to call it before your case statement, depending on what actions you want to take.
Use if else to setBackground color, for example ; if onclick of firsttextview set its color and on click of second change firsttextview color and set seconds color
You have to change the color of all Textviews.
Example t1 is selectable change t1's color as selected and other textviews as unselected,so on for rest of the textviews
It would be better if you use radio group which handles all clicks and selection and highlighting if you have many textviews.
Please check below url.
Url
In that link use answer by Sanjeet Ajnabee. It is excellent. I have been using it.

Android implement navigation

I am trying to learn Android development and have stumbled across the following thing I cannot solve.
I have imported Bottom Bar Navigation via Gradle to my app and have managed to set it up according to instructions. Here is what my screen looks like now.
As you can see, I have three tabs at the bottom that I am trying to use for navigation. The problem however is, that even though I know how to detect which element has been clicked via following:
mBottomBar.setItemsFromMenu(R.menu.bottombar_menu, new OnMenuTabClickListener() {
#Override
public void onMenuTabSelected(#IdRes int menuItemId) {
if (menuItemId == R.id.bb_menu_favorites) {
// The user selected item number one.
}
}
#Override
public void onMenuTabReSelected(#IdRes int menuItemId) {
if (menuItemId == R.id.bb_menu_favorites) {
// The user reselected item number one, scroll your content to top.
}
}
});
I have no idea how to actually perform the navigation request - e.g. when user moves to different tab, I want to show my other screen instead of Hello World! that you can see at the moment.
I believe that for this I need to actually change my activity_main.xml file as currently it looks like this:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
...
tools:context="com.example.robert.testproject.MainActivity">
<include layout="#layout/page_import"/>
</RelativeLayout>
This is where I have ended. As far as my understanding goes, I somehow need to use Intent (correct me if I am wrong) for the navigation purposes, but I am not quite sure how to handle this.
Any help in this matter - switching views, would be more than appreciated.
Use a Fragment for each bottom tab (3 Fragments for 3 views). Have a container layout(maybe a FrameLayout) in the Activity. Each Fragment will have different layouts. Replace the fragments based on what the user has tapped on the bottom bar.

Change FAB position when anchor is gone

im using a coordinatorLayout and a floating action button between two layers, like this:
in the orange part i put a NestedScrollView to show alot of information about the product that have his photo on purple part.
When the users scrolls the layout and the anchor of the FAB ( the image on purple layout) is gone, the FAB keeps on top|right of the layout.
what im trying to do is: when the anchor is gone, the FAB go to buttom|right of the layout insted to remain on top of screen.
can you help me? thanks :)
I've used this code to change the actionbar title when to toolbar collapses. You can reuse it to change the fab position instead of changing the title :
((AppBarLayout) findViewById(R.id.appbar)).addOnOffsetChangedListener(new AppBarStateChangeListener() {
#Override
public void onStateChanged(AppBarLayout appBarLayout, State state) {
switch (state) {
case COLLAPSED:
getSupportActionBar().setTitle(mMatch.getUniversity().getDisplayName());
break;
case NOT_COLLAPSED:
getSupportActionBar().setTitle("");
break;
}
}
});

Categories

Resources