Androidドキュメントに記載されているとおり
スナックバーは、操作に関する軽量のフィードバックを提供します。モバイルでは画面の下部に、大きなデバイスでは左下に短いメッセージが表示されます。
画面の下部ではなく上部にsnackbars
を表示できる代替手段はありますか?
現在、私は画面の下部にsnackbar
を表示するこのようなことをしています。
Snackbar.make(findViewById(Android.R.id.content), "Hello this is a snackbar!!!",
Snackbar.LENGTH_LONG).setAction("Undo", mOnClickListener)
.setActionTextColor(Color.RED)
.show();
これを使用して、スナックバーを画面の上部に表示することができます。
Snackbar snack = Snackbar.make(parentLayout, str, Snackbar.LENGTH_LONG);
View view = snack.getView();
FrameLayout.LayoutParams params =(FrameLayout.LayoutParams)view.getLayoutParams();
params.gravity = Gravity.TOP;
view.setLayoutParams(params);
snack.show();
OPから:
最初の行を変更する必要がありました:
Snackbar snack = Snackbar.make(findViewById(Android.R.id.content), "Had a snack at Snackbar", Snackbar.LENGTH_LONG);
CoordinatorLayout coordinatorLayout=(CoordinatorLayout)findViewById(R.id.coordinatorLayout);
Snackbar snackbar = Snackbar.make(coordinatorLayout, "Text", Snackbar.LENGTH_LONG);
View view = snackbar.getView();
CoordinatorLayout.LayoutParams params=(CoordinatorLayout.LayoutParams)view.getLayoutParams();
params.gravity = Gravity.TOP;
view.setLayoutParams(params);
snackbar.show();
上記のものを組み合わせたソリューション:
final ViewGroup.LayoutParams params = snackbar.getView().getLayoutParams();
if (params instanceof CoordinatorLayout.LayoutParams) {
((CoordinatorLayout.LayoutParams) params).gravity = Gravity.TOP;
} else {
((FrameLayout.LayoutParams) params).gravity = Gravity.TOP;
}
snackbar.getView().setLayoutParams(params);
それでも不適切なアニメーションに悩まされています。
次の方法でSnackBarをレイアウト内の任意の場所に配置できます(このメソッドにはアニメーションの問題はありません)
1)によると:
スナックバーの作成(ビューの表示、CharSequenceテキスト、int期間)
メッセージを表示するスナックバーを作成しますスナックバーは、ビューに指定された値からスナックバーのビューを保持する親ビューを探して見つけます。スナックバーは、CoordinatorLayoutとして定義されている適切な親またはウィンドウ装飾のコンテンツビューのいずれか早い方を見つけるために、ビューツリーを上に向かって進みます。
したがって、コーディネーターレイアウトを目的の場所に追加し、そのコーディネーターレイアウトを上記のSnackbar.makeメソッド内のビュー引数として使用するだけで、スナックバーをレイアウト内の任意の場所に配置できます。
_<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
Android:layout_width="match_parent"
Android:layout_height="match_parent"
xmlns:app="http://schemas.Android.com/apk/res-auto"
tools:context=".MainActivity"
Android:orientation="vertical"
Android:id="@+id/rl"
xmlns:tools="http://schemas.Android.com/tools"
xmlns:Android="http://schemas.Android.com/apk/res/Android">
<!-- Coordinator Layout used to position the SnackBar -->
<Android.support.design.widget.CoordinatorLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:id="@+id/cl"
Android:layout_alignParentTop="true"
Android:background="@Android:color/transparent">
</Android.support.design.widget.CoordinatorLayout>
<!-- add your layout here -->
</RelativeLayout>
_
2)SnackBarを表示するために使用されるコーディネーターレイアウトは、他のすべてのビューの上(最も高い標高)にある必要があります。これを行うには、コーディネーターレイアウトでbringToFront()
を呼び出すか、コーディネーターレイアウトを昇格します(たとえば、_Android:elevation="10dp"
_を追加します)。
3)この時点でスナックバーは目的の場所に表示されますが、スナックバーは下から上へのアニメーションで表示されます(デフォルトの動作)。上から下へのアニメーションを実現するには、次のようにします。
4)ステップ3の後、スナックバーは上から下のアニメーションで表示されますが、メッセージとアクションテキストが回転し、重力が逆転するため、最後のステップとして次のようにしました。
5)例:
_public class MainActivity extends AppCompatActivity {
private final String TAG = MainActivity.class.getSimpleName();
private RelativeLayout rl;
private CoordinatorLayout cl;
private CoordinatorLayout cl1;
private CoordinatorLayout cl2;
private CoordinatorLayout cl3;
private CoordinatorLayout cl4;
private Snackbar snackbar_updated;
private Snackbar snackbar_updated1;
private Snackbar snackbar_updated2;
private Snackbar snackbar_updated3;
private Snackbar snackbar_updated4;
private Snackbar snackbar_ordinary;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
rl = (RelativeLayout) findViewById(R.id.rl);
cl = (CoordinatorLayout) findViewById(R.id.cl);
cl1 = (CoordinatorLayout) findViewById(R.id.cl1);
cl2 = (CoordinatorLayout) findViewById(R.id.cl2);
cl3 = (CoordinatorLayout) findViewById(R.id.cl3);
cl4 = (CoordinatorLayout) findViewById(R.id.cl4);
cl.bringToFront();
cl1.bringToFront();
cl2.bringToFront();
cl3.bringToFront();
cl4.bringToFront();
snackbar_updated = Snackbar.make(cl, "Message", Snackbar.LENGTH_INDEFINITE);
snackbar_updated.setAction("Ok", new View.OnClickListener() {
@Override
public void onClick(View view) {
}
});
/** Snackbar message and action TextViews are placed inside a LinearLayout
*/
final Snackbar.SnackbarLayout snackBarLayout = (Snackbar.SnackbarLayout) snackbar_updated.getView();
for (int i = 0; i < snackBarLayout.getChildCount(); i++) {
View parent = snackBarLayout.getChildAt(i);
if (parent instanceof LinearLayout) {
((LinearLayout) parent).setRotation(180);
break;
}
}
snackbar_updated1 = Snackbar.make(cl1, "Message", Snackbar.LENGTH_INDEFINITE);
snackbar_updated1.setAction("Ok", new View.OnClickListener() {
@Override
public void onClick(View view) {
}
});
/** Snackbar message and action TextViews are placed inside a LinearLayout
*/
final Snackbar.SnackbarLayout snackBarLayout1 = (Snackbar.SnackbarLayout) snackbar_updated1.getView();
for (int i = 0; i < snackBarLayout1.getChildCount(); i++) {
View parent = snackBarLayout1.getChildAt(i);
if (parent instanceof LinearLayout) {
((LinearLayout) parent).setRotation(180);
break;
}
}
snackbar_updated2 = Snackbar.make(cl2, "Message", Snackbar.LENGTH_INDEFINITE);
snackbar_updated2.setAction("Ok", new View.OnClickListener() {
@Override
public void onClick(View view) {
}
});
snackbar_updated3 = Snackbar.make(cl3, "Message", Snackbar.LENGTH_INDEFINITE);
snackbar_updated3.setAction("Ok", new View.OnClickListener() {
@Override
public void onClick(View view) {
}
});
/** Snackbar message and action TextViews are placed inside a LinearLayout
*/
Snackbar.SnackbarLayout snackBarLayout3 = (Snackbar.SnackbarLayout) snackbar_updated3.getView();
for (int i = 0; i < snackBarLayout3.getChildCount(); i++) {
View parent = snackBarLayout3.getChildAt(i);
if (parent instanceof LinearLayout) {
((LinearLayout) parent).setRotation(180);
break;
}
}
snackbar_updated4 = Snackbar.make(cl4, "Message", Snackbar.LENGTH_INDEFINITE);
snackbar_updated4.setAction("Ok", new View.OnClickListener() {
@Override
public void onClick(View view) {
}
});
snackbar_ordinary = Snackbar.make(rl, "Message", Snackbar.LENGTH_INDEFINITE);
snackbar_ordinary.setAction("Ok", new View.OnClickListener() {
@Override
public void onClick(View view) {
}
});
rl.post(new Runnable() {
@Override
public void run() {
snackbar_updated.show();
rl.postDelayed(new Runnable() {
@Override
public void run() {
snackbar_updated1.show();
rl.postDelayed(new Runnable() {
@Override
public void run() {
snackbar_updated2.show();
rl.postDelayed(new Runnable() {
@Override
public void run() {
snackbar_updated3.show();
rl.postDelayed(new Runnable() {
@Override
public void run() {
snackbar_updated4.show();
rl.postDelayed(new Runnable() {
@Override
public void run() {
snackbar_ordinary.show();
}
}, 2000);
}
}, 2000);
}
}, 2000);
}
}, 2000);
}
}, 2000);
}
});
}
}
_
activity_main.xml:
_<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
Android:layout_width="match_parent"
Android:layout_height="match_parent"
xmlns:app="http://schemas.Android.com/apk/res-auto"
tools:context=".MainActivity"
Android:orientation="vertical"
Android:id="@+id/rl"
xmlns:tools="http://schemas.Android.com/tools"
xmlns:Android="http://schemas.Android.com/apk/res/Android">
<!-- Coordinator Layout used to position the SnackBar -->
<Android.support.design.widget.CoordinatorLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:id="@+id/cl"
Android:rotation="180"
Android:layout_alignParentTop="true"
Android:background="@Android:color/transparent">
</Android.support.design.widget.CoordinatorLayout>
<RelativeLayout
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:layout_alignParentTop="true"
Android:orientation="vertical">
<Android.support.design.widget.AppBarLayout
Android:id="@+id/appbar"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:fitsSystemWindows="true">
<Android.support.v7.widget.Toolbar
Android:id="@+id/toolbar"
Android:layout_width="match_parent"
Android:layout_height="?attr/actionBarSize"
Android:background="?attr/colorPrimary"
app:itemIconTint="#333"
app:itemTextColor="#333"
app:layout_collapseMode="pin"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/ThemeOverlay.AppCompat.Dark"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
</Android.support.design.widget.AppBarLayout>
<RelativeLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:orientation="vertical"
Android:layout_below="@id/appbar"
Android:layout_gravity="bottom">
<TextView
Android:layout_width="match_parent"
Android:layout_height="30dp"
Android:id="@+id/tv_top"
Android:text="Layout Top"
Android:gravity="center"
Android:textSize="15sp"
Android:textColor="@Android:color/white"
Android:layout_alignParentTop="true"
Android:background="@color/colorAccent">
</TextView>
<!-- Coordinator Layout used to position the SnackBar -->
<Android.support.design.widget.CoordinatorLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:id="@+id/cl1"
Android:rotation="180"
Android:layout_below="@id/tv_top"
Android:background="@Android:color/transparent">
</Android.support.design.widget.CoordinatorLayout>
<!-- Coordinator Layout used to position the SnackBar -->
<Android.support.design.widget.CoordinatorLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:id="@+id/cl2"
Android:paddingBottom="75dp"
Android:layout_centerInParent="true"
Android:background="@Android:color/transparent">
</Android.support.design.widget.CoordinatorLayout>
<!-- Coordinator Layout used to position the SnackBar -->
<TextView
Android:layout_width="match_parent"
Android:layout_height="30dp"
Android:id="@+id/tv_center"
Android:text="Center"
Android:gravity="center"
Android:textSize="15sp"
Android:layout_centerInParent="true"
Android:textColor="@Android:color/white"
Android:background="@color/colorAccent">
</TextView>
<Android.support.design.widget.CoordinatorLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:id="@+id/cl3"
Android:rotation="180"
Android:paddingBottom="75dp"
Android:layout_centerInParent="true"
Android:background="@Android:color/transparent">
</Android.support.design.widget.CoordinatorLayout>
<TextView
Android:layout_width="match_parent"
Android:layout_height="30dp"
Android:id="@+id/tv_bottom"
Android:text="Layout Bottom"
Android:gravity="center"
Android:textSize="15sp"
Android:textColor="@Android:color/white"
Android:layout_alignParentBottom="true"
Android:background="@color/colorAccent">
</TextView>
<!-- Coordinator Layout used to position the SnackBar -->
<Android.support.design.widget.CoordinatorLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:id="@+id/cl4"
Android:layout_above="@id/tv_bottom"
Android:background="@Android:color/transparent">
</Android.support.design.widget.CoordinatorLayout>
</RelativeLayout>
</RelativeLayout>
</RelativeLayout>
_
6)結果:
val snackBarView = Snackbar.make(view, "SnackBar Message" , Snackbar.LENGTH_LONG)
val view = snackBarView.view
val params = view.layoutParams as FrameLayout.LayoutParams
params.gravity = Gravity.TOP
view.layoutParams = params
view.background = ContextCompat.getDrawable(context,R.drawable.custom_drawable) // for custom background
snackBarView.animationMode = BaseTransientBottomBar.ANIMATION_MODE_FADE
snackBarView.show()
以下の行はアニメーションの問題を解決します。
snackBarView.animationMode = BaseTransientBottomBar.ANIMATION_MODE_FADE
代替ソリューション-snackBarView.anchorView = mention viewId above whom you want to show SnackBar
2年後、これが私の解決策です。
上余白と下余白を設定すると、効果の結果が変わります...できるだけ多くのカスタマイズオプションを追加しようとしましたが、アニメーションのオーバーライドは、ここに記載されていない別のオプションです。
いくつかの質問に対する全員の回答のおかげで...
{
// usage for setSnackBar
int view = R.id.toolbar;
String snackMessage = "";
boolean useAction = false;
Runnable ifUseActionRunnable = null;
String actionText = "";
int leftMargin = 0;
int topMargin = 0;
int rightMargin = 0;
int bottomMargin = 0;
int backgroundColour = Color.BLACK;
int textColor = Color.WHITE;
int duration = Snackbar.LENGTH_LONG;
setSnackBar(view, snackMessage, useAction, ifUseActionRunnable, actionText, leftMargin, topMargin, rightMargin, bottomMargin, backgroundColour, textColor, duration);
}
Snackbar snb;
public void setSnackBar(int targetView, String snackMessage, boolean useAction, final Runnable ifUseActionRunnable, String actionText , int leftMargin, int topMargin, int rightMargin, int bottomMargin, int backgroundColour, int textColor, int duration)
{
snb = Snackbar.make(findViewById(targetView), snackMessage, duration);
View view = snb.getView();
view.setBackgroundColor(backgroundColour);
snb.setActionTextColor(textColor);
FrameLayout.LayoutParams params =(FrameLayout.LayoutParams)view.getLayoutParams();
params.gravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP;
params.setMargins(leftMargin, topMargin, rightMargin, bottomMargin);
view.setLayoutParams(params);
if (useAction)
{
snb.setAction(actionText, new View.OnClickListener(){
@Override
public void onClick(View p1)
{
ifUseActionRunnable.run();
}
});
}
if (snb.isShown())
{
snb.dismiss();
snb.show();
}
else
{
snb.show();
}
}