Сделать закусочную без просмотра?
Я хочу показать закусочную, как только пользователь откроет активность в Google Картах, но дело в том, что нет никаких видов в действии для использования в качестве первого параметра активности (в findViewById()
of 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();
}
}
Кроме того, здесь представлен код операции 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" />
И, наконец, здесь ошибка stacktrace:
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)
Спасибо за помощь!:)
Ответы
Ответ 1
Я вижу некоторые варианты... Не уверен, какой из них может решить вашу проблему.
Простейшая
SupportMapFragment
расширяет класс android.support.v4.app.Fragment
. Таким образом, у него есть метод getView()
Snackbar.make(mapFragment.getView(), "Click the pin for more options", Snackbar.LENGTH_LONG).show();
Найти корневой вид
Из этого ответа есть способ получить представление root с помощью:
getWindow().getDecorView().getRootView()
Так что, может быть, вы можете сделать:
Snackbar.make(getWindow().getDecorView().getRootView(), "Click the pin for more options", Snackbar.LENGTH_LONG).show();
ПРИМЕЧАНИЕ: У этого подхода есть побочный эффект, упомянутый в комментариях ниже:
Сообщение будет отображаться за нижней панелью навигации, если для получения представления будет использоваться следующий метод getWindow(). GetDecorView(). GetRootView()
Добавьте фиктивную LinearLayout, чтобы получить представление
Честно говоря, я не уверен, возможно ли это решение. Я не уверен, что вы можете добавить LinearLayout над фрагментом Maps... Я думаю, что это нормально, но так как я никогда раньше не работал с 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>
а затем:
Snackbar.make(findViewById(R.id.dummy_layout_for_snackbar), "Click the pin for more options", Snackbar.LENGTH_LONG).show();
Ответ 2
Как указывает Шахаб Рауф, получение представления через 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();
}
}
Ответ 3
Попробуйте это в любой деятельности:
snackbar(findViewById(android.R.id.content),"your text")
Ответ 4
Я бы сказал, что findViewById
- лучший подход. При использовании getWindow().getDecorView().getRootView()
сообщение будет отображаться за нижней панелью навигации.
В моем случае мне не нужно было создавать фиктивный элемент в XML. Я использовал следующий код
Snackbar.make(findViewById(R.id.container),"This will start payment process.", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
и мой файл XML выглядит следующим образом
<android.support.design.widget.CoordinatorLayout
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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".HomePatientActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/appbar_padding_top"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_weight="1"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/AppTheme.PopupOverlay">
</android.support.v7.widget.Toolbar>
<android.support.design.widget.TabLayout
android:id="@+id/sliding_tabs"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
app:layout_anchorGravity="top"
app:tabMode="fixed" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
</android.support.v4.view.ViewPager>
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="@dimen/fab_margin"
app:srcCompat="@android:drawable/ic_dialog_email" />
</android.support.design.widget.CoordinatorLayout>
Ответ 5
Добавьте любой макет и присвойте макету пример id ниже:
<RelativeLayout
android:id="@+id/relativeLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="@+id/map_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="com.google.android.gms.maps.SupportMapFragment"
/>
</RelativeLayout>
В вашей деятельности найдите макет, используя findViewById:
RelativeLayout relativeLayout = findViewById(R.id.relativeLayout);
Пример для других макетов соответственно, если вы назначите макетам их идентификаторы:
LinearLayout relativeLayout = findViewById(R.id.linearLayout);
FrameLayout frameLayout = findViewById(R.id.frameLayout);
Отображение Снэк-бара:
Snackbar.make(relativeLayout,"You are displaying a Snackbar",Snackbar.LENGTH_SHORT).show();
Для других макетов просто измените имя примеров макетов:
Snackbar.make(linearLayout,"You are displaying a Snackbar",Snackbar.LENGTH_SHORT).show();
Snackbar.make(frameLayout,"You are displaying a Snackbar",Snackbar.LENGTH_SHORT).show();
Ответ 6
Не делай этого.
Почему?
Вся идея предоставления привязки к закусочной, вероятно, заключается в том, что она дает нам возможность поместить ее в наше любимое место на экране,
Как упоминалось в других ответах, есть способы, с помощью которых вы можете автоматически прикрепить к нему корневое представление. Использование getWindow().getDecorView().getRootView()
является одним из них, но может привести к тому, что это сообщение появится в нижнем навигационном представлении, что выглядит не очень хорошо (по крайней мере, для меня).
Если вы хотите что-то для общего отображения сообщений, перейдите на тост, это гораздо менее подвержено ошибкам и имеет постоянный внешний вид, если вам нужно что-то с взаимодействием, я бы предложил диалог оповещения