I have a Snackbar in need to set its height or set height to wrap content. Is there any way?
Snackbar snack = Snackbar.make(findViewById(R.id.activity_container), "Message", Snackbar.LENGTH_SHORT);
View view = snack.getView();
TextView tv = (TextView) view.findViewById(android.support.design.R.id.snackbar_text);
view.setBackgroundColor(Color.RED);
tv.setTextColor(Color.WHITE);
tv.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
tv.setGravity(Gravity.CENTER_HORIZONTAL);
We are going to provide multiple answers. First a statement or two! You can set the height and width of a Snackbar but it is messy and time consuming period.
One realization about a Snackbar widget is most tutorials do not talk about styling. The opinion is they should be just the size that the widget gives you NOT MY VIEW. So we have noticed that the text size and number of max lines plays a BIG roll is the size of a well styled Snackbar. So design your Snackbar and style away
OK how to implement the mess Suggestion DO NOT DO THIS declare this variable where you would declare any other variable in your Activity
RelativeLayout rl;
Then when you need to increase the size of your RelativeLayout that is in your XML file but is not the root Layout in this case use this code
rl = (RelativeLayout) findViewById(R.id.svRL);
rl.getLayoutParams().height = 1480;
When you get done with this increased size which can mess with the size of other object in the root Layout you might want to set the size of the root Layout back to what it was. In this case the root Layout was set to layout height 615dp we are working with a Nexus 7 Tablet. If you have not noticed this yet here is the MESS part that 1480 is in units of pixels and you need it in dp. I am sure the conversion can be made just do not ask me. So here is the set back line of code
rl.getLayoutParams().height = 1230;
Now for a easy way to design and style two types of Snackbar's one with an Action button and one with out. First you need a CoordinatorLayout in what ever Activity corresponding XML file that looks like this Note it has an id
<android.support.design.widget.CoordinatorLayout
android:id="#+id/coorSB"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true" >
<!-- android.support.design.widget.SnackBar -->
<!--stuff you want inside the coordinator ... -->
</android.support.design.widget.CoordinatorLayout>
Now we are ready to do some work in the Activity to design and style after a little advanced string and color set up. Please do not be offended I am being very thorough because you seem to be very new to programming.
<string name="snackbar_text">I Am a NEW SnackBAR TEXT</string>
<string name="snackbar_action">EXIT</string>
<string name="second_text">Second Text</string>
<string name="csb_text">I am the Custom Guy</string>
<string name="csb_action">EXIT</string>
<string name="the_text">Password must have one Numeric Value\n"
"One Upper & Lower Case Letters\n"
"One Special Character $ # ! % * ? &\n"
"NO Spaces in the PASSWORD"</string>
Now for the Rainbow many ways to manage Color this is my mine.
<resources>
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303f9f</color>
<color name="colorAccent">#FF4081</color>
<color name="color_Black">#000000</color>
<color name="color_White">#FFFFFF</color>
<color name="color_darkGray">#606060</color>
<color name="color_lightGray">#C0C0C0</color>
<color name="color_super_lightGray">#E0E0E0</color>
<color name="color_Red">#FF0000</color>
<color name="color_Yellow">#FFFF66</color>
<color name="color_deepBlue">#0000ff</color>
<color name="color_lightBlue">#3333FF</color>
<color name="color_Purple">#9C27B0</color>
<color name="color_Transparent">#android:color/transparent</color>
Done with house keeping in your Activity where you declare variables add this
private CoordinatorLayout myLayout;
Snackbar sb = null;
private CoordinatorLayout noActLayout;
Snackbar sbNoAct = null;
There here is the implementation of both types of Snackbars
public void makeNoAct(View view){
// this is declared on a Button android:onClick="makeNoAct"
noActLayout = (CoordinatorLayout)findViewById(R.id.coorSB);
sbNoAct = Snackbar.make(noActLayout,R.string.the_text,1);// any interger will make it happy
sbNoAct.setDuration(3000);// 3 sec // OR Snackbar.LENGTH_LONG
// matters NOT you are setting duration
View sbView = sbNoAct.getView();
sbView.setBackgroundColor(ContextCompat.getColor(this, R.color.color_Black));
TextView textViewNoAct = (TextView) sbView.findViewById(android.support.design.R.id.snackbar_text);
//set text color
textViewNoAct.setTextColor(ContextCompat.getColor(this,R.color.color_Yellow));
textViewNoAct.setMaxLines(10);
textViewNoAct.setTextSize(24);
//increase max lines of text in snackbar. default is 2.
sbNoAct.show();
int height = sbView.getHeight();
etNewData.setText(String.valueOf(height));
}
public void makeCOOR(View view) {
// this is declared on a Button android:onClick="makeCOOR"
// We were to Lazy to write an OnClickListener
myLayout = (CoordinatorLayout) findViewById(R.id.coorSB);
sb = Snackbar.make(myLayout, R.string.csb_text, Snackbar.LENGTH_INDEFINITE)
.setAction(R.string.csb_action, myOnClickListener)
.setActionTextColor(ContextCompat.getColor(context, R.color.color_Red));
View sbView = sb.getView();
sbView.setBackgroundColor(ContextCompat.getColor(this, R.color.color_White));
TextView textView = (TextView) sbView.findViewById(android.support.design.R.id.snackbar_text);
//set text color
textView.setTextColor(ContextCompat.getColor(this,R.color.color_deepBlue));
textView.setTextSize(30);
//increase max lines of text in snackbar. default is 2.
textView.setMaxLines(10);
// NOTE new View
TextView textAction = (TextView) sbView.findViewById(android.support.design.R.id.snackbar_action);
//set Action text color
textAction.setTextColor(ContextCompat.getColor(this,R.color.color_Red));
textAction.setTextSize(30);
sb.show();
}
View.OnClickListener myOnClickListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
// OR use and Intent to go somewhere have a nice trip
sb.dismiss();
System.out.println("========= I WAS DISMISSED ===============");
}
};
Enjoy the code and let us know with a comment if this solves your issue.
This is very simple to change the height or width of Snackbar .
Just we need to write 2 , 3 line of code to do this.
Check the below code snippet .
Snackbar snackbar = Snackbar.make(view, "Your message", Snackbar.LENGTH_LONG);
snackbar.setAction("Ok", new View.OnClickListener() {
#Override
public void onClick(View view) {
//your click action.
}
});
Snackbar.SnackbarLayout layout = (Snackbar.SnackbarLayout)snackbar.getView();
layout.setMinimumHeight(50);//your custom height.
snackbar.show();
final String CR= System.getProperty("line.separator") ;
String snackMsg= "First line" + CR;
snackMsg+="Second line." +CR;
snackMsg+="... more lines." +CR;
final Snackbar snack = Snackbar.make(findViewById(android.R.id.content), snackMsg, Snackbar.LENGTH_INDEFINITE);
snack.setAction("OK", new View.OnClickListener() {
#Override
public void onClick(View v) {
// Respond to the click, such as by undoing the modification that caused
// this message to be displayed
}
});
View view = snack.getView();
TextView tv = (TextView) view.findViewById(android.support.design.R.id.snackbar_text);
// tv.setBackgroundColor(Color.RED);
tv.setLines(12);
FrameLayout.LayoutParams params =(FrameLayout.LayoutParams)view.getLayoutParams();
params.gravity = Gravity.TOP;
//params.height=2000;
params.bottomMargin=10;
view.setLayoutParams(params);
snack.show();
You may also need to set the size for the inner container of a snackbar in order for the text to be aligned/centered vertically. Here is a solution (Kotlin):
Snackbar.make( containerView, msg, duration ).also {
// outer container
it.view.minimumHeight = minHeightPx
// inner container
( it.view as? Snackbar.SnackbarLayout )?.getChildAt( 0 )?.let { innerView ->
innerView.minimumHeight = minHeightPx
}
}.show()
Snackbar snack = Snackbar.make(findViewById(R.id.activity_container), "Message", Snackbar.LENGTH_SHORT);
View view = snack.getView();
TextView tv = (TextView) view.findViewById(android.support.design.R.id.snackbar_text);
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams)tv.getLayoutParams();
params.height = 80;
tv.setTextColor(Color.WHITE);
tv.setGravity(Gravity.CENTER_HORIZONTAL);
tv.setLayoutParams(params);
snack.show();
Related
After login, I want to change text in TextView near profile on name_user.
But it doesn't change textView visually.
It is worth to mention, that when outputting (Toast), it gives out the data that is needed, but does not visually display it. Everything is fine with the TextView parameters (I think), because if you set the finished text in the parameters( i mean android:text="smth"), it visually displays it.
Java code:
`protected void onCreate(Bundle savedInstanceState) {
yourLayout = getLayoutInflater().inflate(R.layout.layout_navigation_header, null);
profileName = yourLayout.findViewById(R.id.profName); //
Intent intent = getIntent(); // Get data from previous activity.
String name_user = intent.getStringExtra("name");
String email_user = intent.getStringExtra("email");
String password_user = intent.getStringExtra("password");
profileName.setText(name_user); //0 changes, textView still don't change.
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_menu2);
DrawerLayout drawerLayout = findViewById(R.id.drawerLayout);
Toast toast = Toast.makeText(getApplicationContext(), profileName.getText().toString(),
Toast.LENGTH_SHORT); // for debug, it works and show profileName that contains name_user, but.
toast.show();
findViewById(R.id.imageMenu).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
drawerLayout.openDrawer(GravityCompat.START);
}
});
}`
Part of main XML
`<com.google.android.material.navigation.NavigationView
android:id="#+id/navigationView"
android:layout_width="wrap_content"
android:layout_height="match_parent"
app:headerLayout="#layout/layout_navigation_header"// layour_navigation_header -here is TextView
app:menu='#menu/navigation_menu'
android:layout_gravity="start"/>`
Part of layour_navigation_header with TextView that I need to change.
`<TextView
android:id="#+id/profName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:textColor="#color/black"
android:textSize="18sp"
android:text="Temporary"
app:layout_constraintBottom_toTopOf="#id/viewSupporter"
app:layout_constraintStart_toEndOf="#id/imageProfile"/>`
Hope you could help me
I tried to move
`yourLayout = getLayoutInflater().inflate(R.layout.layout_navigation_header, null);
profileName = yourLayout.findViewById(R.id.profName); //
Intent intent = getIntent(); // Get data from previous activity.
String name_user = intent.getStringExtra("name");
String email_user = intent.getStringExtra("email");
String password_user = intent.getStringExtra("password");
profileName.setText(name_user); //0 changes, textView still don't change`
before
`super.onCreate(savedInstanceState);
setContentView(R.layout.activity_menu2);`
but final result remains the same. It contains data, but not visually displays it.
You're inflating layout_navigation_header layout and setting a value in one of its textviews. But you never seem to place the layout on screen, the layout instance simply gets discarded.
What gets displayed is the activity_menu2 layout you inflate and set as content view with setContentView(). If that layout includes layout_navigation_header or its look-a-like with some mechanism, it's not the same instance you inflated earlier.
To solve the issue, just call setContentView() to set your desired layout, call findViewById() to find the textview and set a text to it.
I have a method that displays snackbars which is called from many different fragments. Here is the code of this method:
public static void showSnackBar(Activity activity, String message, View root) {
int duration = 5000;
Snackbar currentSnackBar = Snackbar.make( activity, root, message, Snackbar.LENGTH_INDEFINITE).setDuration(duration);
View sbView = currentSnackBar.getView();
sbView.setBackgroundColor(ContextCompat.getColor(activity, R.color.colorBlue));
FrameLayout.LayoutParams params =(FrameLayout.LayoutParams)sbView.getLayoutParams();
params.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
sbView.setLayoutParams(params);
currentSnackBar.setAnimationMode(BaseTransientBottomBar.ANIMATION_MODE_FADE);
currentSnackBar.show();
}
Currently it shows the snackbar at the top center of the display. I would like to have the following formatting modifications:
The textsize should be bigger
The text should be aligned in the center. At the moment it is aligned to the left.
Reminder: do you know how I can do this?
You can access the snacker textview by doing -
val textView =
sbView.findViewById<TextView>(R.id.snackbar_text)
Then set whatever properties you want, to this textview
I'm trying to get my button to create a text field where the user can input information. This way they can only create as many lines as they would like. Also, is there a way to create multiple fields at once?
So, it'll end up being something like this:
"Add Event" (rest of the screen is blank until they click on that button)
Text field 1/ Text field 2/ Text field 3
(once they press that button and of course without the underlines, just an example)
So they can put in information that they want there. If they want another row, they click on the add button again.
Am I supposed to be using an onClickListener? I'm confused as to how I would go about making the button create that field for the user.
public class BudgetScreen extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_budget_screen);
Button addBillExpense = (Button) findViewById(R.id.addBillExpense);
addBillExpense.setOnClickListener(new Button.OnClickListener() {
public void onClick (View v) {
TextView inputField = new TextView(BudgetScreen.this);
}
});
}
}
That is what I have so far. I've been stuck on this for a hot minute. I am aware that I haven't used "inputField" yet.
Suppose you have the following layout xml:
<LinearLayout ...>
<Button .../>
<LinearLayout ...
android:id="#+id/holder"
android:orientation="vertical">
</LinearLayout>
</LinearLayout>
in button onClickListener you can have something like:
LinearLayout layout = (LinearLayout) findViewById(R.id.holder);
EditText et = new EditText(this);
LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT);
layout.addView(et,lp);
You can change the LayoutParams to get the layout you like.
If you want multiple EditText in a single row, you can do the following:
final int NUM_EDITTEXT_PER_ROW = 3;
LinearLayout layout = (LinearLayout) findViewById(R.id.holder);
Display display = ((WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
int width = display.getWidth()/NUM_EDITTEXT_PER_ROW;
LinearLayout tempLayout = new LinearLayout(this);
tempLayout.setOrientation(LinearLayout.HORIZONTAL);
for(int i=0;i<NUM_EDITTEXT_PER_ROW;i++){
EditText et = new EditText(this);
LayoutParams lp = new LayoutParams(width,LayoutParams.WRAP_CONTENT);
tempLayout.addView(et,lp);
}
layout.addView(tempLayout);
I build Snackbar by this code:
Snackbar sb = Snackbar.make(drawer, "message", Snackbar.LENGTH_LONG)
.setAction("action", new View.OnClickListener() {
#Override
public void onClick(View view) {
}
});
Now I want to change the typeface of message and action button but can't find any solution, How to do that?
You can set TypeFace by getting view from Snack bar
TextView tv = (TextView) (mSnackBar.getView()).findViewById(android.support.design.R.id.snackbar_text);
Typeface font = Typeface.createFromAsset(getContext().getAssets(), "fonts/font_file.ttf");
tv.setTypeface(font);
For AndroidX, use resource ID com.google.android.material.R.id.snackbar_text
Styling Both the Snackbar Text and Action
You can use the same method to style both the snackbar_text and snackbar_action.
Once you've created a snackbar, you can use the following to get the Views associated with the text and the action and then apply whatever adjustments to the view.
Snackbar snackbar = Snackbar.make( ... ) // Create the Snackbar however you like.
TextView snackbarActionTextView = (TextView) snackbar.getView().findViewById( android.support.design.R.id.snackbar_action );
snackbarActionTextView.setTextSize( 20 );
snackbarActionTextView.setTypeface(snackbarActionTextView.getTypeface(), Typeface.BOLD);
TextView snackbarTextView = (TextView) snackbar.getView().findViewById(android.support.design.R.id.snackbar_text);
snackbarTextView.setTextSize( 16 );
snackbarTextView.setMaxLines( 3 );
In my example, I've set the Action to be font size 20 and Bold, and the Text to be size 16 and allow up to 3 lines.
For AndroidX
android.support.design.R.id.snackbar_text won't be available.
Use com.google.android.material.R.id.snackbar_textinstead.
If you are using kotlin, then I prefer you to use extension function:
fun Snackbar.changeFont()
{
val tv = view.findViewById(com.google.android.material.R.id.snackbar_text) as TextView
val font = Typeface.createFromAsset(context.assets, "your_font.ttf")
tv.typeface = font
}
and call it like:
mSnakeBar.changeFont()
In addition to this answer: now package to find snackbar's textview by id is
val snackText = snackView.findViewById<TextView>(
com.google.android.material.R.id.snackbar_text)
Get the snack bar view and apply customization
TextView tv = (TextView) sb.getView().findViewById(android.support.design.R.id.snackbar_text);
tv.setTextColor(Color.WHITE);
tv.setTypeface(Typeface.createFromAsset(
getAssets(),
"fonts/ur_file.ttf"));
Or this
SpannableStringBuilder snackbarText = new SpannableStringBuilder();
snackbarText.append("Add ");
int boldStart = snackbarText.length();
snackbarText.append("bold color");
snackbarText.setSpan(new ForegroundColorSpan(0xFFFF0000), boldStart, snackbarText.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
snackbarText.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), boldStart, snackbarText.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
snackbarText.append(" to Snackbar text");
Snackbar.make(view, snackbarText, Snackbar.LENGTH_LONG).show();
Or you can give a look at this and this.
Thank you.
For those who are still reading this 7 years later, you can change the text appearance of the snackbar for the whole app by overriding its theme parent in your themes.xml file.
<style name="Theme.App" parent="Theme.MaterialComponents.*">
...
<item name="snackbarTextViewStyle">#style/Widget.App.SnackbarTextView</item>
</style>
<style name="Widget.App.SnackbarTextView" parent="Widget.MaterialComponents.Snackbar.TextView">
<item name="android:textAppearance">#style/your_snackbar_text_style</item>
</style>
And then in your styles.xml file insert the your_snackbar_text_style style there
<style name="your_snackbar_text_style">
<item name="android:fontFamily">#font/your_font</item>
</style>
Starting from Support Library 26, fonts can be used as resources.
val mainTextView = view.findViewById(com.google.android.material.R.id.snackbar_text) as TextView
val font = ResourcesCompat.getFont(applicationContext, R.font.your_font)
mainTextView.typeface = font
Get assets
AssetManager assets = context.getAssets();
Get Typeface
Typeface typeface = Typeface.createFromAsset(assets,PATH OF .TTF FILE);
Path: font/robotoregular.ttf (if .ttf file is stored in assets/font path)
if you want to change the font of Action Button and textview use this code :
Snackbar.make(this,message,Snackbar.LENGTH_LONG).also {snackbar ->
snackbar.setAction("ok"){
snackbar.dismiss()
}
val actionButton = snackbar.view.findViewById(com.google.android.material.R.id.snackbar_action) as Button
val textview = snackbar.view.findViewById(com.google.android.material.R.id.snackbar_text) as TextView
val font = Typeface.createFromAsset(context.assets, "fonts/your_custom_font")
actionButton.typeface = font
textview.typeface = font
ViewCompat.setLayoutDirection(snackbar.view,ViewCompat.LAYOUT_DIRECTION_RTL)
}.show()
For every one that crashes when calling createFromAsset() you can use
Font font = ResourcesCompat.getFont(getApplicationContext(), R.font.your_font);
I'm trying to tell my title to respect that there's a date next to him, so I want to change his width to that of the background, minus the date. But sometimes getMeasuredWidth returns wrong values, or just 0. How do I go about doing this? This method is called for every item.
private void populateNewsItems(int pos, List<NewsItem> mFeedItems) {
NewsItem newsItem = mFeedItems.get(pos);
View newsContainer = getActivity().getLayoutInflater().inflate(R.layout.list_item_news, null);
TextView background = (TextView) newsContainer.findViewById(R.id.background);
TextView title = (TextView) newsContainer.findViewById(R.id.title);
TextView colorBlock = (TextView) newsContainer.findViewById(R.id.colorBlock);
TextView date = (TextView) newsContainer.findViewById(R.id.date);
TextView description = (TextView) newsContainer.findViewById(R.id.description);
title.setText(newsItem.getTitle());
date.setText(newsItem.getDate());
description.setText(newsItem.getDescription());
title.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
date.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
background.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
RelativeLayout.LayoutParams paramsTitle = (RelativeLayout.LayoutParams) title.getLayoutParams();
paramsTitle.width = background.getMeasuredWidth() - date.getMeasuredWidth();
title.setLayoutParams(paramsTitle);
Log.e("LOG", String.format("background width:%d ; date width:%d", background.getMeasuredWidth(), date.getMeasuredWidth()));
linearLayout.addView(newsContainer);
}
It reads the date width absolutely correct. But that's probably because it's the same before that textview gets filled.
At the point that you're asking for the dimensions, your view hasn't been actually drawn yet. If your layout is static, it's best to do it in the XML, but if it's truly dynamic, then you'll want to use an OnGlobalLayoutListener to wait until the view has been first drawn and then resize it. Some code:
newsContainer.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
// title.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
// date.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
// background.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
RelativeLayout.LayoutParams paramsTitle = (RelativeLayout.LayoutParams) title.getLayoutParams();
// paramsTitle.width = background.getMeasuredWidth() - date.getMeasuredWidth();
paramsTitle.width = background.getWidth() - date.getWidth();
title.setLayoutParams(paramsTitle);
title.requestLayout();
}
});
There is a much simpler solution than trying to manually calculate the width. In your xml document containing R.id.title and R.id.background, try structuring the views a little something like this:
<RelativeLayout // this is built to match the width of the background
android:width="wrap_content"
android:height="wrap_content"/>
<TextView
android:width="wrap_content"
android:height="wrap_content"
android:id="#+id/background"/>
<RelativeLayout
android:width="match_parent"
android:height="wrap_content"/>
<TextView
android:width="wrap_content"
android:height="wrap_content"
android:id="#+id/date"
android:layout_alignParentRight="true"/> // This aligns the date to the
// right side of the view
<TextView
android:width="match_parent" // this fills the container which matches the width of background, currently
android:height="wrap_content"
android:id="#+id/title"
android:layout_alignLeft="#id/date"/> // and this makes sure the view doesn't overlap the date.
The ordering in this actually does matter. You want to list the title after the date so you can reference the date view in the title view. Let me know if you have any more questions and good luck!