在没有视图的情况下制作小吃吧?

Kel*_*ner 40 java xml crash android android-snackbar

我想尽快展示的小吃店为用户打开谷歌地图的活动,但问题是,有在活动中没有意见,该活动的第一个参数使用(在findViewById()Snackbar.make()).我放在那里?这是java类代码:

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {

private GoogleMap mMap;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_maps);

    // Obtain the SupportMapFragment and get notified when the map is ready to be used.
    SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
            .findFragmentById(R.id.map);
    mapFragment.getMapAsync(this);
}

@Override
public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;
    mMap.setBuildingsEnabled(true);
    mMap.getUiSettings().setZoomControlsEnabled(true);
    float cameraZoom = 17;
    LatLng location = new LatLng(43.404032, -80.478184);
    mMap.addMarker(new MarkerOptions().position(location).title("49 McIntyre Place #18, Kitchener, ON N2R 1G3"));
    CameraUpdateFactory.newLatLngZoom(location, cameraZoom);
    Snackbar.make(findViewById(/*WHAT DO I PUT HERE?*/), "Click the pin for more options", Snackbar.LENGTH_LONG).show();
}
}
Run Code Online (Sandbox Code Playgroud)

另外,这里是活动xml代码:

<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="ca.davesautoservice.davesautoservice.MapsActivity" />
Run Code Online (Sandbox Code Playgroud)

最后,这是堆栈跟踪错误:

08-03 11:42:21.333 3901-3901/? E/AndroidRuntime: FATAL EXCEPTION: main
    Process: ca.davesautoservice.davesautoservice, PID: 3901
    java.lang.NullPointerException
        at android.support.design.widget.Snackbar.<init>(Snackbar.java:183)
        at android.support.design.widget.Snackbar.make(Snackbar.java:215)
        at ca.davesautoservice.davesautoservice.MapsActivity.onMapReady(MapsActivity.java:48)
        at com.google.android.gms.maps.SupportMapFragment$zza$1.zza(Unknown Source)
        at com.google.android.gms.maps.internal.zzo$zza.onTransact(Unknown Source)
        at android.os.Binder.transact(Binder.java:361)
        at xz.a(:com.google.android.gms.DynamiteModulesB:82)
        at maps.ad.u$5.run(Unknown Source)
        at android.os.Handler.handleCallback(Handler.java:808)
        at android.os.Handler.dispatchMessage(Handler.java:103)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:5333)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:515)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:828)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:644)
        at dalvik.system.NativeStart.main(Native Method)
Run Code Online (Sandbox Code Playgroud)

谢谢您的帮助!:)

W0r*_*0le 69

我看到一些选项......不确定哪一个可以解决您的问题.

Simpliest

SupportMapFragment扩展课程android.support.v4.app.Fragment.这样,它有一个方法getView()

Snackbar.make(mapFragment.getView(), "Click the pin for more options", Snackbar.LENGTH_LONG).show();
Run Code Online (Sandbox Code Playgroud)

查找根视图

从这个答案,有一种方法可以通过以下方式获取根视图:

getWindow().getDecorView().getRootView()
Run Code Online (Sandbox Code Playgroud)

所以,也许,你可以这样做:

Snackbar.make(getWindow().getDecorView().getRootView(), "Click the pin for more options", Snackbar.LENGTH_LONG).show();
Run Code Online (Sandbox Code Playgroud)

添加虚拟LinearLayout以获取视图

老实说,我不确定这个解决方案是否可行.我不确定你是否可以在Maps片段上面添加一个LinearLayout ...我认为它没问题,但由于我以前从未使用过Maps API,所以我不确定.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/dummy_layout_for_snackbar"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <fragment 
        xmlns:map="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/map"
        android:name="com.google.android.gms.maps.SupportMapFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="ca.davesautoservice.davesautoservice.MapsActivity" />
</LinearLayout>
Run Code Online (Sandbox Code Playgroud)

然后:

Snackbar.make(findViewById(R.id.dummy_layout_for_snackbar), "Click the pin for more options", Snackbar.LENGTH_LONG).show();
Run Code Online (Sandbox Code Playgroud)

  • 如果使用以下方法来获取视图`getWindow().getDecorView().getRootView(),则消息将显示在底部导航栏后面. (17认同)

小智 10

在任何活动中试试这个:

snackbar(findViewById(android.R.id.content),"your text")
Run Code Online (Sandbox Code Playgroud)


小智 6

正如Shahab Rauf指出的那样,通过getDecorView()获取视图可能会将快餐栏放在底部导航栏的后面。我使用以下代码:(使用并扩展至您满意)

public class BaseActivity extends AppCompatActivity {

    private View getRootView() {
        final ViewGroup contentViewGroup = (ViewGroup) findViewById(android.R.id.content);
        View rootView = null;

        if(contentViewGroup != null)
            rootView = contentViewGroup.getChildAt(0);

        if(rootView == null)
            rootView = getWindow().getDecorView().getRootView();

        return rootView;
    }

    protected void showSnackBarWithOK(@StringRes int res) {
        final View rootView = getRootView();
        if(rootView != null) {
            final Snackbar snackbar = Snackbar.make(getRootView(), res, Snackbar.LENGTH_INDEFINITE);
            snackbar.setAction(R.string.ok, new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    snackbar.dismiss();
                }
            });

            snackbar.show();
        }
    }

    protected void showSnackBar(@StringRes int res) {
        final View rootView = getRootView();
        if(rootView != null)
            Snackbar.make(rootView, res, Snackbar.LENGTH_LONG).show();
    }
}
Run Code Online (Sandbox Code Playgroud)


Kis*_*nki 6

好的,所以上述所有解决方案要么太复杂,要么不相关。

最简单的解决方案是在任何地方使用此功能

fun showSnackBar(message: String?, activity: Activity?) {
    if (null != activity && null != message) {
        Snackbar.make(
            activity.findViewById(android.R.id.content),
            message, Snackbar.LENGTH_SHORT
        ).show()
    }
}
Run Code Online (Sandbox Code Playgroud)

想在Activity中调用这个函数吗?

showSnackBar("Test Message in snackbar", this)
Run Code Online (Sandbox Code Playgroud)

想在Fragment中调用这个函数吗?

showSnackBar("Test Message in snackbar", requireActivity())
Run Code Online (Sandbox Code Playgroud)

快乐编码!