I have a map view for android maps api v2 in an activity that uses this sliding menu https://github.com/iPaulPro/SlidingMenu. The sliding menu works great except for on the map page. There is a black view covering the sliding menu that is the exact size of the map. This is an example with the map height set at 100dp to outline what I mean.
If I touch that view it will go away. How would I get rid of it or make it transparent? I've tried the requestTransparentRegion() trick. No dice there.
Found this stack overflow post ViewPager with Google Maps API v2: mysterious black view and used this class in place of the normal map fragment.
package com.myapp.gms.maps;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.FrameLayout;
import com.google.android.gms.maps.SupportMapFragment;
/**
* #author btate
*/
public class TransparentSupportMapFragment extends SupportMapFragment {
public TransparentSupportMapFragment() {}
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup view,
Bundle savedInstance) {
View layout = super.onCreateView(inflater, view, savedInstance);
FrameLayout frameLayout = new FrameLayout(getActivity());
frameLayout.setBackgroundColor(
getResources().getColor(android.R.color.transparent));
((ViewGroup) layout).addView(frameLayout,
new ViewGroup.LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT
)
);
return layout;
}
}
TransparentSupportMapFragment solved the problem for android 2.3.7
Thank you!
There is one more solution to this problem. I am showing MapFragment within another fragment. The MapFragment is dynamically added into the a FrameLayout.
The solution is to use frameLayout.setVisibility(View.Visible) and frameLayout.setVisibility(View.Gone) on open and close events of sliding menu. It doesn't require an extra view to be added. And the black area is completely gone.
getSlidingMenu().setOnOpenListener(
new OnOpenListener() {
#Override
public void onOpen() {
frameLayout.setVisibility(View.GONE);
}
}
);
getSlidingMenu().setOnClosedListener(
new OnClosedListener() {
#Override
public void onClosed() {
frameLayout.setVisibility(View.VISIBLE);
}
}
);
Related
I could solve how to hide or show a Floating Action Button from a fragment when I call it.
But I faced with another problem that I didn't know how to solve it, when I rotate my phone,
the FAB appears again.
You can see my code below and how I did to hide my FAB, but how to keep it when my phone rotate from
Portrait to Landscape?
package com.example.cursobaralhocigano.ui.deck;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Toast;
import com.example.cursobaralhocigano.MainActivity;
import com.example.cursobaralhocigano.R;
import com.example.cursobaralhocigano.classes.cBaralhos;
import com.example.cursobaralhocigano.dao.uLibSql;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
/**
* A simple {#link Fragment} subclass.
*/
public class DeckFragment extends Fragment implements View.OnClickListener {
private uLibSql DB;
private cBaralhos baralho = new cBaralhos();
CheckBox ck01, ck02, ck03, ck04, ck05;
ImageButton Img;
public DeckFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
LinearLayout ln;
View view = inflater.inflate(R.layout.fragment_deck, container, false);
final FloatingActionButton fab = ((MainActivity) getActivity()).findViewById(R.id.fab);
if (fab.isShown()) {
fab.hide();
}
return view;
}
Thanks a lot for help
Regards
Alex
You have to correctly save the instance state of Fragment you should do the following:
In the fragment, save instance state by overriding onSaveInstanceState() and restore in onActivityCreated():
Below link may help you
https://stackoverflow.com/a/17135346/10239870
I am trying to avoid the following situation in the activity( screen shot of the activity). When I add the margins using setMargins it does not work. I have tried adding margins via xml code and the end result is achieved but it very time consuming and it can't be guaranteed that it will work for all devices. How can i do it in code?
Here is the code.
package com.example.android.tourguide;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.NavigationView;
import android.support.design.widget.TabLayout;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.ViewPager;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.MenuItem;
import android.widget.FrameLayout;
public class TouristAttractions extends AppCompatActivity {
private DrawerLayout mDrawerLayout;
private NavigationView mNavigationView;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.menu_item);
/*
Finding the Toolbar that is defined in activity_main.xml via the id toolbar.
Note:The following three lines should be repeated for all the activities that are opened from the MainActivity. Also the toolbar should have an orientation
which is not zero.
*/
android.support.v7.widget.Toolbar toolbar = (android.support.v7.widget.Toolbar) findViewById(R.id.toolbar_for_menu_items);
/*
Setting the action bar as the toolbar defined in the above code line
*/
setSupportActionBar(toolbar);
/*
Setting the title text color of the app bar.
*/
toolbar.setTitleTextColor(ContextCompat.getColor(this, R.color.color_of_text_of_app_bar));
mNavigationView = (NavigationView) findViewById(R.id.navigation_view);
/*
Finding the drawerLayout so that when the user clicks on the menu item of the navigation drawer it should close as we invoke the method closeDrawers()
*/
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mNavigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem menuItem) {
if (menuItem.getItemId() == R.id.home_menu) {
/*
Opening the home class that is the MainActivity when the Tourist Home menu button is clicked.
*/
Intent intentToOpenHomeClass = new Intent(TouristAttractions.this, MainActivity.class);
startActivity(intentToOpenHomeClass);
} else if (menuItem.getItemId() == R.id.entertainment_menu) {
Intent intentToOpenEntertainmentClass = new Intent(TouristAttractions.this, Entertainment.class);
startActivity(intentToOpenEntertainmentClass);
} else if (menuItem.getItemId() == R.id.gardens_menu) {
Intent intentToOpenGardenClass = new Intent(TouristAttractions.this, Garden.class);
startActivity(intentToOpenGardenClass);
} else {
mDrawerLayout.closeDrawers();
}
return true;
}
});
TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout_for_menu_items);
ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager_for_menu_items);
AdapterForFragmentOfTouristAttraction adapterForFragmentOfTouristAttraction = new AdapterForFragmentOfTouristAttraction(this, getSupportFragmentManager());
viewPager.setAdapter(adapterForFragmentOfTouristAttraction);
tabLayout.setupWithViewPager(viewPager);
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) toolbar.getLayoutParams();
params.setMargins(0, toolbar.getHeight(), 0, 0);
ActionBar actionbar = getSupportActionBar();
/*
actionBar.setDisplayHomeAsUpEnabled(true) will make the icon clickable and add the < at the left of the icon.
*/
actionbar.setDisplayHomeAsUpEnabled(true);
/*
Enabling the menu icon of the navigation.However note we are simply adding the menu icon however clicking on the icon does absolutely nothing.
*/
actionbar.setHomeAsUpIndicator(R.drawable.baseline_menu_white_24);
}
}
First of all, it might be a better idea to use a LinearLayout with a vertical orientation, a RelativeLayout, or a ConstraintLayout to position views below one another. In more exotic use cases even a CoordinatorLayout might be better suited.
FrameLayouts are mostly used to simply overlay views on one another, without depdendencies between them.
This said, the issue you are facing occurs because you use toolbar.getHeight() right after adding the view, which will always be 0. Try attaching a debugger and see for yourself!
The reason is that Android needs a bit of time to measure -> layout -> draw its views, and if you call getHeight right after adding the layout it will not have done either of those steps, leaving the values uninitialized, at 0.
There are ways around that, but again, you would be better off using a different layout alltogether. If you insist on using a FrameLayout the cleanest approach would be to extend it and create your own, where you can measure and layout the view yourself. The hacky, hard to maintain, and confusing approach would be to use ViewTreeObserver to listen for the changes and react to them. This is bad because you have to wait for a full layout pass before you trigger yet another one.
Don't use a FrameLayout here.
You havn't Done
yourView.setLayoutParams(params);
I have built an app for crypto currencies, to maintain a portfolio. I planned to show the latest news items in the same app.
The whole project is an Android app done in LibGdx.
Question
How to have a webview for the area "Part-B"?
LigGdx have anything like WebView?
Does LibGdx has any extensions to take care of WebView?
Screenshot
Starting with your last two questions; no. LibGDX does currently no extensions, nor native support for webviews or something similar. You can, however, create a custom layout. LibGDX has a initializeForView method, which you can use to grab the View itself. This is inflated in a Fragment, which is added to the layout itself. The WebView is then the other view.
First off, the launcher:
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import com.badlogic.gdx.backends.android.AndroidFragmentApplication;
public class AndroidLauncher extends FragmentActivity implements AndroidFragmentApplication.Callbacks {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.gdxwebview);
// Create the fragment
GDXWithWebview fragment = new GDXWithWebview();
getSupportFragmentManager().beginTransaction().
add(R.id.fragmentRoot, fragment).
commit();
}
#Override
public void exit() {}
}
Since fragments are involved, the launcher is different from the generated launcher
For the fragment:
The reason behind using a fragment is to inflate LibGDX into the fragment, which ends up as a sub-unit of the activity. If you set the content view in the activity, you will not get a WebView in there as well.
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.badlogic.gdx.backends.android.AndroidFragmentApplication;
public class GDXWithWebview extends AndroidFragmentApplication{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
// return the GLSurfaceView on which libgdx is drawing game stuff
AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();//Configure with whatever you need
return initializeForView(new MyGdxGame(), config);//WARNING!! Replace MyGdxGame with your game class.
}
}
And finally, the layout. It's a basic layout, and the weights (/sizes) may need tweaking for you to get it to look just like you want it to
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import com.badlogic.gdx.backends.android.AndroidFragmentApplication;
public class AndroidLauncher extends FragmentActivity implements AndroidFragmentApplication.Callbacks {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.gdxwebview);//The layout; comes later
// Create the fragment
GDXWithWebview fragment = new GDXWithWebview();
getSupportFragmentManager().beginTransaction().
add(R.id.fragmentRoot, fragment).
commit();//Add the fragment
}
#Override
public void exit() {}
}
In addition, if you plan on using the WebView to go online, you need the Internet permission (if you use it to execute JavaScript or other web content locally, without going on the Internet, you shouldn't need it):
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.badlogic.gdx.backends.android.AndroidFragmentApplication;
public class GDXWithWebview extends AndroidFragmentApplication{
View root;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
// return the GLSurfaceView on which libgdx is drawing game stuff
AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();//Configure with whatever you need
root = initializeForView(new MyGdxGame(), config);//WARNING!! Replace MyGdxGame with your game class.
//declaredInTheClassWebView = (WebView) root.findViewById(R.id.webView);//For initialization, make sure you call root.findViewById, not findViewById. You have to specify the view in which to find the ID when dealing with Fragments.
return root;
}
}
And per the LibGDX documentation on use with Fragments, you also need the v4 support library. Assuming you use Gradle 4.1 and Android Studio:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/fragmentRoot"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
</FrameLayout>
<WebView android:id="#+id/webView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="9"/>
</LinearLayout>
If you use an earlier version of Gradle and the Gradle plugin:
<uses-permission android:name="android.permission.INTERNET" />
And if you don't use Gradle, find the appropriate call for your build system. If you don't have a build system, grab the jar manually and add it to the classpath.
I need to know when my fragment is visible, I was using setMenuVisibility but I now know it's not a good option. I'm trying to implement setUserVisibleHint on a FragmentStatePagerAdapter Fragment, however it never gets called.
import android.app.Fragment;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
public class Contacts extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View view = inflater.inflate(R.layout.fragment_screen_contacts, container, false);
return view;
}
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
Log.d("MyFragment", "This never shows up.");
Toast.makeText(getActivity(), "Neither does this", Toast.LENGTH_LONG).show();
}
}
I'm running API level 19, and set a minimum API Level of 15 on my AndroidManifest. Is there anything else to do to get setUserVisibleHint, what am I doing wrong?
setUserVisibleHint is available so that you have a way to tell the system the fragment is in fact not visible and not the other way around, when you are doing some fancy fragment transactions that specifically hide it. You can't use it to determine visibility and it defaults to true.
You should use the isVisible call to know if the fragment is visible and onAttach of the fragment or the root view classes to get callbacks when it's been attached to the activity or the respective root views.
setUserVisibleHint()
only works in a FragmentPagerAdapter.
Please refer to Is Fragment.setUserVisibleHint() called by the android System?
package com.example.app;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.app.ActionBarActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getSupportFragmentManager().findFragmentById(android.R.id.content) == null) {
getSupportFragmentManager().beginTransaction()
.add(android.R.id.content, new PlaceholderFragment()).commit();
}
}
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
return rootView;
}
}
}
When I run this code in a 4.3 emulator I get the desired "Hello world!" message. In the 2.3.3 emulator howerer I get a blank screen (ActionBar does get displayed).
Apparently this is a known bug for Android 2.3 and below. There is a filed bug for this here.
Solution for support library versions prior to v19:
Try creating an XML layout for the Activity (i.e. just a ViewGroup like LinearLayout or RelativeLayout and give it an id). Then call setContentView(R.layout.newLayout) in the Activity's onCreate(). Then use the id of the ViewGroup as the first parameter of FragmentTransaction.add().
This issue has been resolved as of version 19 of the support library. If you update to the latest version of the support library using the SDK manager your code should work.
You might also find post #6 on the link above helpful.