Reputation: 6013
I am using the Support Library to add a bottom bar similar to the material design one. The bottom bar works great but it seems that if I have the bar displayed, if I try to open any fragment from my custom adapter, the fragment does not open...or maybe it opens behind my main layout? I have no idea how to figure this out. Below is my code.
I've read more posts on SO and around the web and I think this is related to the fragment being properly loaded but below or next to the bottom bar...and that is why it isn't visible? Why does this happen? Is it because the bottom bar has a LinearLayout? I defined it as a menu so I'm not sure if I can control it being a LinearLayout....
Setting up the bottom bar, this method is called from the onCreate of my activity:
public void setupBottomToolbar(Bundle savedInstanceState) {
mBottomBar = BottomBar.attach(MainActivity.this, savedInstanceState);
mBottomBar.setItems(R.menu.bottombar_menu);
mBottomBar.setOnMenuTabClickListener(new OnMenuTabClickListener() {
@Override
public void onMenuTabSelected(@IdRes int menuItemId) {
if (menuItemId == R.id.toolbar_jobs) {
} else if (menuItemId == R.id.toolbar_messages) {
} else if (menuItemId == R.id.toolbar_recentJobs) {
} else if (menuItemId == R.id.toolbar_employerPools) {
}
}
@Override
public void onMenuTabReSelected(@IdRes int menuItemId) {
if (menuItemId == R.id.toolbar_jobs) {
// The user reselected item number one, scroll your content to top.
} else if (menuItemId == R.id.toolbar_messages) {
} else if (menuItemId == R.id.toolbar_employerPools) {
} else if (menuItemId == R.id.toolbar_recentJobs) {
}
}
});
// Setting colors for different tabs when there's more than three of them.
// You can set colors for tabs in three different ways as shown below.
mBottomBar.getBar().setBackgroundColor(getResources().getColor(R.color.laborswipe_darkgray));
mBottomBar.setActiveTabColor(getResources().getColor(R.color.laborswipe_lightgray));
// Make a Badge for the second tab, with red background color and a value of "13".
BottomBarBadge unreadMessages = mBottomBar.makeBadgeForTabAt(1, getResources().getColor(R.color.laborswipe_orange), 5);
// Control the badge's visibility
unreadMessages.show();
//unreadMessages.hide();
// Change the displayed count for this badge.
//unreadMessages.setCount(4);
// Change the show / hide animation duration.
unreadMessages.setAnimationDuration(200);
// If you want the badge be shown always after unselecting the tab that contains it.
unreadMessages.setAutoShowAfterUnSelection(true);
// If you don't want this badge to be hidden after selecting the tab contains it.
unreadMessages.setAutoShowAfterUnSelection(false);
}
In my adapter, I am trying to open the fragment when you click a button, like this:
holder.desc.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(context, "Open Description", Toast.LENGTH_SHORT).show();
JobDescFragment firstFragment = new JobDescFragment();
((MainActivity)context).getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container, firstFragment).commit();
}
});
If I comment out the call to setupBottomToolbar() in my onCreate of the activity, the fragment opens up fine...but that means I don't have the bottom bar...
What am I missing? There has to be a way to use the bottom bar and also open a fragment?
Thanks!
Here is the top part of my activity.
public class MainActivity extends AppCompatActivity {
private ArrayList<String> swipecardsList;
private ArrayList<Job> jobList = new ArrayList<Job>();
private JobAdapter arrayAdapter; //arrayadapter
private BottomBar mBottomBar;
SharedPreferences settings;
@InjectView(R.id.frame) SwipeFlingAdapterView flingContainer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Remove title bar
//this.requestWindowFeature(Window.FEATURE_NO_TITLE);
//color the notification bar with our company colors
Window window = this.getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.setStatusBarColor(this.getResources().getColor(R.color.laborswipe_notificationbar));
//remove title from action bar and add the logo to the top left of the action bar
setupTopToolbar();
setContentView(R.layout.activity_main);
ButterKnife.inject(this);
//set up the bottom toolbar using the roughike library to mimic android material design
setupBottomToolbar(savedInstanceState);
My adapter:
public class JobAdapter extends ArrayAdapter<Job> {
private final Context context;
private final ArrayList<Job> jobs;
private final int layoutResourceId;
private final SwipeFlingAdapterView flingContainer;
private boolean isExpanded = false;
public JobAdapter(Context context, int layoutResourceId, ArrayList<Job> jobs, SwipeFlingAdapterView flingContainer) {
super(context, layoutResourceId, jobs);
this.context = context;
this.jobs = jobs;
this.layoutResourceId = layoutResourceId;
this.flingContainer = flingContainer;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
final ViewHolder holder;
String pay, hrs;
final Bundle fragmentParams = new Bundle();
LayoutInflater inflater = LayoutInflater.from(context);
if (view == null) {
view = inflater.inflate(layoutResourceId, parent, false);
holder = new ViewHolder();
holder.title = (TextView)view.findViewById(R.id.tv_jobTitle);
holder.desc = (TextView) view.findViewById(R.id.tv_JobDesc);
view.setTag(holder);
} else {
holder = (ViewHolder)view.getTag();
}
Job j = jobs.get(position);
holder.title.setText(j.getJobTitle());
holder.desc.setText(j.getDescription());
//when user clicks apply, swipe the card right
holder.apply.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// Open up a fragment to display the entire job description
Toast.makeText(context, "Applied", Toast.LENGTH_SHORT).show();
flingContainer.getTopCardListener().selectRight();
}
});
//when user clicks dismiss, swipe the card left
holder.dismiss.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// Open up a fragment to display the entire job description
Toast.makeText(context, "Dismissed", Toast.LENGTH_SHORT).show();
flingContainer.getTopCardListener().selectLeft();
}
});
//on click event listener for the job description field - open larger window to read description
holder.desc.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//Toast.makeText(context, "Open Description", Toast.LENGTH_SHORT).show();
JobDescFragment firstFragment = new JobDescFragment();
Fragment frag = new Fragment();
frag = firstFragment.newJobDescFrag(j.getDescription());
((MainActivity) context).getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, frag)
.addToBackStack("JobDesc").commit();
}
});
return view;
}
public class ViewHolder
{
TextView title;
TextView payrate;
TextView dateRange;
TextView workinghrs;
TextView location;
TextView companyname;
TextView desc;
TextView experience;
TextView equipment;
Button apply, dismiss, expand;
}
}
activity_main.xml:
<merge
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<com.lorentzos.flingswipe.SwipeFlingAdapterView
android:id="@+id/frame"
android:background="@color/laborswipe_lightgray"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:context=".MainActivity"
android:layout_gravity="top" />
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</merge>
Fragment Layout:
<FrameLayout 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=".JobDescFragment">
<LinearLayout
android:id="@+id/outerDescriptionLayout"
android:layout_width="match_parent"
android:layout_height="400dp"
android:layout_gravity="center_horizontal|top"
android:orientation="vertical"
android:background="@drawable/swipecard_shadow"
android:gravity="top"
android:layout_marginLeft="5dp">
<LinearLayout
android:id="@+id/DescriptionLayout"
android:layout_width="match_parent"
android:layout_height="400dp"
android:layout_gravity="center_horizontal|top"
android:orientation="vertical"
android:weightSum="1"
android:gravity="top"
android:layout_marginTop="20dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:background="#00FF00"
android:clickable="true">
<TextView
android:layout_width="200dp"
android:layout_height="200dp"
android:text="Detailed Description:"
android:textColor="#000000"
android:id="@+id/tv_title" />
<TextView
android:layout_width="200dp"
android:layout_height="200dp"
android:text="THIS IS THE FULL DESCRIPTION"
android:textColor="#000000"
android:id="@+id/tv_fullDescription" />
</LinearLayout>
</LinearLayout>
</FrameLayout>
Logcat:
08-07 11:20:47.799 13896-13896/com.lorentzos.swipecards.example I/System.out: DEBUG: job desc fragment loaded!
08-07 11:20:47.855 13896-13941/com.lorentzos.swipecards.example W/EGL_emulation: eglSurfaceAttrib not implemented
08-07 11:20:47.855 13896-13941/com.lorentzos.swipecards.example W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0xaaa7f880, error=EGL_SUCCESS
08-07 11:20:48.002 13896-13941/com.lorentzos.swipecards.example V/RenderScript: 0xa1408000 Launching thread(s), CPUs 2
08-07 11:20:49.798 13896-13941/com.lorentzos.swipecards.example E/Surface: getSlotFromBufferLocked: unknown buffer: 0xae433ca0
When I use the bottom bar (not working- no fragment opened but toast displayed):
When I don't use the bottom bar (workin-fragment opened, background is green):
Upvotes: 7
Views: 594
Reputation: 8277
OK, I think the solution for this should be simple, from what I can see in your code, you are attaching the BottomBar to your activity, I think this is the problem. If you were to read the readme.md in the roughike/BottomBar github page you'd find this
Why is it overlapping my Navigation Drawer?
All you need to do is instead of attaching the BottomBar to your Activity, attach it to the view that has your content. For example, if your fragments are in a ViewGroup that has the id fragmentContainer, you would do something like this:
mBottomBar.attach(findViewById(R.id.fragmentContainer), savedInstanceState);
So, since navigation drawer works with transition a fragment in and out of view with animation, the same thing is happening when you are adding a new fragment to your activity.
The Solution
From what I can see in your code, your fragment container id is this: fragment_container
in your activity layout. So according to the documentation you'd just need to do attach your bottomBar to the fragment_container
instead of MainActivity.this
mBottomBar.attach(findViewById(R.id.fragment_container), savedInstanceState);
If the above doesn't work try this
What you'd need to do is add an extra FrameLayout to hold your bottombar, which has a transparent background, but is on top of your fragment.
So change your main_activity layout to
<merge
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<com.lorentzos.flingswipe.SwipeFlingAdapterView
android:id="@+id/frame"
android:background="@color/laborswipe_lightgray"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:context=".MainActivity"
android:layout_gravity="top" />
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<FrameLayout
android:id="@+id/holder_bottombar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/transparent"/>
</merge>
Now in the code instead of attaching the bottom bar to mainactivity, just attach it to the holder like so
mBottomBar.attach(findViewById(R.id.holder_bottombar), savedInstanceState);
Upvotes: 0
Reputation: 37404
try to link a pic of problem and without problem(no bottombar) and since you are using merge
the layout hierarchy will be laid off according to your activity's
viewgroup
(linear,relative) constraints
(we don't know what they are like).
as you said when there is no bottombar ,you fragment displays perfectly though when the bottombar it there ,problem stats ,as per your log in fragment indicating that your fragment is loading perfectly even though when bottombar is visible mean fragment is there but is not visible ,seems like your fragment didn't get the appropriate space to get displayed.
other solution can be adding bottom bar to your fragment instead of activity to avoid any overlapping ,like
mBottomBar.attach(findViewById(R.id.fragmentContainer), savedInstanceState);
Upvotes: 1