Android: BottomSheetMenuItem doesn't show icon in Menu - android

I am trying to show icons in BottomSheeet but only text shows. I read lot of threads on SO but none of them seem to help or are old.
Seeking help on latest android version. Appreciate any help.
List<MenuItem> bottomSheetMenuItems = new ArrayList<>(optionsList.size());
Drawable drawable = getResources().getDrawable(android.R.drawable.ic_dialog_email,
getContext().getTheme());
MenuItem bottomSheetMenuItem = new BottomSheetMenuItem(
getContext(),
someId,
"Test",
drawable);
bottomSheetMenuItem.setChecked(true).setChecked(true);
bottomSheetMenuItems.add(bottomSheetMenuItem);
BottomSheet bottomSheet = new BottomSheet
.Builder(getContext())
.setTitle("Test Title")
.setMenuItems(bottomSheetMenuItems)
.create();
bottomSheet.show();

For icons, you would have to create an xml for bottomsheet.
XML example
<LinearLayout app:layout_behavior="android.support.design.widget.BottomSheetBehavior"
android:id="#+id/intervalBottomSheet"
android:layout_width="match_parent"
android:layout_height="400dp"
android:orientation="vertical"
android:background="?attr/colorPrimary"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<ImageView
android:src="#drawable/ic_remove_red_eye_black_24dp" />
<TextView
android:text="MenuItem" />
Java code
final BottomSheetDialog mBottomSheetDialog = new BottomSheetDialog(getActivity());
View sheetView = getActivity().getLayoutInflater().inflate(R.layout.bottomsheet_interval, null);
mBottomSheetDialog.setContentView(sheetView);
mBottomSheetDialog.show();
If your menu items are dynamic and not constant, you could use a recyclerview in the bottomsheetdialog.
With that in mind, you'll need to do this to load the icons
ImageView img= (ImageView) findViewById(R.id.image);
img.setImageResource(R.drawable.my_image);

Related

2x2 buttons in a scrollview

I’m trying to put a matrix (2 x 2) of buttons into a constraint layout and then to put the constraint (with the 4 buttons included) layout into a scroll view and finally to add the scroll view into the main layout. The code is provided here below. Can anyone tell me what do I wrong since finally the bar appears instead of the matrix of buttons? It was planned to have 4 buttons visible, but in fact 2 buttons is appearing. Are there any suggestion how to make the task smarter way. Thank you in advance!
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ConstraintLayout layout = findViewById(R.id.layout);
ConstraintLayout.LayoutParams params = new ConstraintLayout.LayoutParams(200, 200);
ConstraintLayout constraintLayout = new ConstraintLayout(MainActivity.this);
constraintLayout.setLayoutParams(params);
GradientDrawable shape1 = new GradientDrawable();
shape1.setColor(Color.BLUE);
GradientDrawable shape2 = new GradientDrawable();
shape2.setColor(Color.GREEN);
Button button11 = new Button(MainActivity.this);
Button button12 = new Button(MainActivity.this);
Button button21 = new Button(MainActivity.this);
Button button22 = new Button(MainActivity.this);
ConstraintLayout.LayoutParams params01 = new ConstraintLayout.LayoutParams(100,100);
button11.setLayoutParams(params01);
button11.setX(0);
button11.setY(0);
constraintLayout.addView(button11);
ConstraintLayout.LayoutParams params02 = new ConstraintLayout.LayoutParams(100,100);
button12.setLayoutParams(params02);
button12.setX(100);
button12.setY(0);
constraintLayout.addView(button12);
ConstraintLayout.LayoutParams params03 = new ConstraintLayout.LayoutParams(100,100);
button21.setLayoutParams(params03);
button21.setX(0);
button21.setY(100);
constraintLayout.addView(button21);
ConstraintLayout.LayoutParams params04 = new ConstraintLayout.LayoutParams(100,100);
button22.setLayoutParams(params04);
button22.setX(100);
button22.setY(100);
constraintLayout.addView(button22);
ScrollView SV = new ScrollView(MainActivity.this);
ConstraintLayout.LayoutParams SVparams = new ConstraintLayout.LayoutParams(300,300);
SV.setLayoutParams(SVparams);
constraintLayout.setBackground(shape1);
SV.setBackground(shape2);
SV.addView(constraintLayout);
layout.addView(SV);
}
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:id="#+id/layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
</androidx.constraintlayout.widget.ConstraintLayout>
My solution:
ConstraintLayout.LayoutParams params03 = new ConstraintLayout.LayoutParams(100,100);
params03.topToTop = PARENT_ID;
params03.setMargins(0, 100, 0, 0);
button21.setLayoutParams(params03);
button21.setX(0);
constraintLayout.addView(button21);
ConstraintLayout.LayoutParams params04 = new ConstraintLayout.LayoutParams(100,100);
params04.topToTop = PARENT_ID;
params04.setMargins(0, 100, 0, 0);
button22.setLayoutParams(params04);
button22.setX(100);
constraintLayout.addView(button22);
It looks like there's a bug when you put a ConstraintLayout inside a ScrollView. The ConstraintLayout's height defaults to WRAP_CONTENT. So when you set it to any other heights, it won't change. Also setY does not work. You have to set vertical constraints for the buttons in the bottom row to position them vertically.
Result:
If your target is really just simple 2x2 button grid(matrix), then I'm wondering why should you need to achieve this dynamically, when you can just describe all the layout in xml even if its just a fragment for some more complex view or, say, a list/grid item; moreover, you already have xml describing your ConstraintLayout. So in perspective it may look like this:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="300dp"
android:layout_height="300dp"
android:background="#8FFF0E">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#105BFF">
<Button
android:id="#+id/btnFirst"
android:layout_width="100dp"
android:layout_height="100dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<Button
android:id="#+id/btnSecond"
android:layout_width="100dp"
android:layout_height="100dp"
app:layout_constraintStart_toEndOf="#id/btnFirst"
app:layout_constraintTop_toTopOf="parent"/>
<Button
android:id="#+id/btnThird"
android:layout_width="100dp"
android:layout_height="100dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/btnFirst"/>
<Button
android:id="#+id/btnFourth"
android:layout_width="100dp"
android:layout_height="100dp"
app:layout_constraintStart_toEndOf="#id/btnThird"
app:layout_constraintTop_toBottomOf="#id/btnSecond"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
After having it all in prepared view, you can either operate buttons by ids (either, hiding/showing them or changing their properties).
By the topic - you obviously can do it programmatically with the help of ConstraintSet. Check this one: ConstraintLayout: change constraints programmatically

how to customize Dialog header in android studio?

I'm using a custom dialog that I've created in a separate xml file in my project, and I'm coloring the main window a blueish tint,
but the main header still remains the default white color.
Is there no way to change the font color, size, background for the header?
Is the only thing I can change in the header the text?
xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:background="#3edfbc"
android:orientation="vertical">
<TextView
android:id="#+id/textaligmentManager_loader_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#ffffff"
android:text="Initlizing Wifi"
android:textAppearance="?android:attr/textAppearanceLarge" />
<com.github.ybq.android.spinkit.SpinKitView xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/barcodeScanning_spinkit"
style="#style/SpinKitView.Large.FoldingCube"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_below="#+id/textaligmentManager_loader_textview"
android:padding="20dp"
android:layout_centerHorizontal="true"
app:SpinKit_Color="#ffffff" />
</RelativeLayout>
dialog:
Dialog dialog = new Dialog(Scanning_Barcode_Activity.this);
dialog.setContentView(R.layout.aligment_manager_loader_layout);
dialog.setTitle("Loading");
dialog.setCancelable(false);
//set up text
loaderScreenMainText = (TextView) dialog.findViewById(R.id.textaligmentManager_loader_textview);
loaderScreenMainText.setText("Loading Wifi");
//progressBar = (ProgressBar) dialog.findViewById(R.id.barcodeScanning_spinkit);
//DoubleBounce doubleBounce = new DoubleBounce();
//progressBar.setIndeterminateDrawable(doubleBounce);
//now that the dialog is set up, it's time to show it
dialog.show();
You can use AlertDialog which is a subclass of Dialog class. Here you can define a custom layout containing everything such as title, body and buttons. No extra title section will appear. Here is a demo:
AlertDialog.Builder builder = new AlertDialog.Builder(Scanning_Barcode_Activity.this);
builder.setCancelable(false);
LayoutInflater inflater = LayoutInflater.from(Scanning_Barcode_Activity.this);
View dialogView = inflater.inflate(R.layout.aligment_manager_loader_layout, null);
TextView loaderScreenMainText = (TextView) dialogView.findViewById(R.id.textaligmentManager_loader_textview);
loaderScreenMainText.setText("Loading Wifi");
builder.setView(dialogView);
AlertDialog dialog = builder.create();
dialog.show();
Design your custom layout in such a way that the layout itself contains the header part. And then skip this code:
dialog.setTitle("Loading");
Instead add this statement:
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
You can also use AlertDialog. In that case requestWindowFeature() method is not required.
android.support.v7.app.AlertDialog.Builder builder = new android.support.v7.app.AlertDialog.Builder(Scanning_Barcode_Activity.this);
LayoutInflater inflater = LayoutInflater.from(Scanning_Barcode_Activity.this);
View customView = inflater.inflate(your_layout, null);
builder.setCancelable(false);
loaderScreenMainText = (TextView) customView.findViewById(R.id.textaligmentManager_loader_textview);
loaderScreenMainText.setText("Loading Wifi");
builder.setView(customView);
AlertDialog dialog = builder.create();
dialog.show();
There are plenty of stylish open source libraries that you can use for customizing header parts.
Here I'm sharing my newly developed open source library : PanterDialog
Hope it will help you.

Divider line in dialog

I noticed something very useful in Google apps.
When we have dialog with big content, divider line is showing in order to emphasize ability to scroll, like in this two pictures:
But, I have no idea how to implement such behaviour using known utils.
Best example is while choosing phone ring, at the start there is only divider on the bottom, but when we start scrolling two dividers appear.
QUESTION
How to implement appearing and disappearing behaviour in dialog?
If you have custom layout like this
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/scroll_container"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<LinearLayout
android:id="#+id/views_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" />
</ScrollView>
you can inflate View and find ScrollView by
v.findViewById(R.id.scroll_container)
and set scroll TOP and BOTTOM indicators if you have TITLE above and BUTTONS below your custom view
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
final int indicators = View.SCROLL_INDICATOR_TOP | View.SCROLL_INDICATOR_BOTTOM;
scrollView.setScrollIndicators(indicators, View.SCROLL_INDICATOR_TOP | View.SCROLL_INDICATOR_BOTTOM);
}
The behaviour that you want to achieve comes with a Dialog with Scrollable Content. Please read this document to get an idea of that.
In this case, you need to create your own custom layout xml with ListView and couple of buttons. And you need to keep this entire layout under ScrollView.
The following is just a dummy code to help you with:
Edited the dummy code with the actual one::
layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_height="wrap_content"
android:layout_width="match_parent">
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/ListView"/>
</LinearLayout>
MainActivity.class:
LayoutInflater inflater= LayoutInflater.from(this);
view=inflater.inflate(R.layout.layout, null);
ListView listView = (ListView)view.findViewById(R.id.ListView);
String[] items = { "Milk", "Butter", "Yogurt", "Toothpaste", "Ice Cream" };
ArrayAdapter adapter_dest = new ArrayAdapter(this,android.R.layout.simple_list_item_1,items);
listView.setAdapter(adapter_dest);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Custom Dialog")
.setCancelable(false)
.setView(view)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alert = builder.create();
alert.show();
Hope this helps!
Looking at Android source code the solution is really simple. Just add this code to your custom view:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
final int indicators = (hasTopPanel() ? View.SCROLL_INDICATOR_TOP : 0)
| (hasBottomPanel() ? View.SCROLL_INDICATOR_BOTTOM : 0);
view.setScrollIndicators(indicators, View.SCROLL_INDICATOR_TOP | View.SCROLL_INDICATOR_BOTTOM);
}

Android Spinner Toolbar style

How do I achieve the material design of spinner in toolbox? I tried the following but my spinner looks like this
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="56dp"
android:background="#color/main_color"
app:contentInsetLeft="14dp"
app:contentInsetRight="14dp"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
app:theme="#style/ThemeOverlay.AppCompat.ActionBar">
<Spinner
android:id="#+id/spinner_nav"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</android.support.v7.widget.Toolbar>
My minimum sdk is 15.
on my onCreate
ButterKnife.inject(this);
mToolbar.inflateMenu(R.menu.menu_login);
mToolbar.setTitle(R.string.sign_in);
mToolbar.setOnMenuItemClickListener(this);
SpinnerAdapter spinnerAdapter = ArrayAdapter.createFromResource(this,
R.array.options, android.R.layout.simple_spinner_dropdown_item);
mSpinner.setAdapter(spinnerAdapter);
mSpinner.setOnItemSelectedListener(this);
A menu is a temporary sheet of paper that always overlaps the App Bar,
rather than behaving as an extension of the App Bar.
any links would be a great help
UPDATE
I have managed to achieve what I want
I used this
ButterKnife.inject(this);
mToolbar.setTitle(R.string.sign_in);
setSupportActionBar(mToolbar);
SpinnerAdapter spinnerAdapter = ArrayAdapter.createFromResource(getSupportActionBar().getThemedContext(),
R.array.options, android.R.layout.simple_spinner_dropdown_item);
getSupportActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
getSupportActionBar().setListNavigationCallbacks(spinnerAdapter, this);
and my xml
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="56dp"
android:background="#color/app_secondary_color"
app:contentInsetLeft="14dp"
app:contentInsetRight="14dp"
app:popupTheme="#style/ThemeOverlay.AppCompat"
app:theme="#style/ThemeOverlay.AppCompat.ActionBar">
</android.support.v7.widget.Toolbar>
But How do I make It white and the text color of the menu is blue?
also I have this problem. it seems it is too far away? any way to fix this dropdown arrow?
Update 2
Well after spending so much time trying, I have achieve how to make it white and the text color black
through this. I have created my custom layout for dropdown style
<?xml version="1.0" encoding="utf-8"?>
<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/text1"
style="?android:attr/spinnerDropDownItemStyle"
android:singleLine="true"
android:layout_width="match_parent"
android:background="#color/background_material_light"
android:textColor="#color/abc_primary_text_material_light"
android:layout_height="48dp"
android:ellipsize="marquee"/>
then added this code on my oncreate
spinnerAdapter.setDropDownViewResource(R.layout.custom_simple_spinner_dropdown_item);
The Only Problem now I encounter is that the press state is not working, it is just a plane white. if you see on the other pop up menu, when you click an item the background color becomes a little bit darker. Also this annoying icon is still too far from the text.
If u want press state to work, you should add a Drawable selector instead of color as a background.
Selector example:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/numpad_button_bg_selected" android:state_selected="true"></item>
<item android:drawable="#drawable/numpad_button_bg_pressed" android:state_pressed="true"></item>
<item android:drawable="#drawable/numpad_button_bg_normal"></item>
</selector>
You should make a color state list resource and apply it as background for your CheckedTextView. As for arrow icon being too far, AFAIK it's because of the length of the children, it goes as far as the longest child. So, no way to customize that.
try this code for change first item font color or background color for Spinner
Spinner spinner = findViewById(R.id.spn);
ArrayList<String> lst = new ArrayList<>();
lst.add("Android");
lst.add("Iphone");
lst.add("Windows");
ArrayAdapter<String> adapter = new ArrayAdapter<String >(getApplicationContext(),R.layout.spin_item,lst)
{
public View getDropDownView(int position, #Nullable View convertView, #NonNull ViewGroup parent)
{
View v = null;
if (position == 0) {
TextView tv = new TextView(getContext());
tv.setTextColor(Color.parseColor("#007f00"));
v = tv;
}
else {
v = super.getDropDownView(position, null, parent);
}
return v;
}
};
spinner.setAdapter(adapter);
We can use PopupWindow to display views/spinner over given view using showAsDropDown().
LayoutInflater layoutInflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
#SuppressLint("InflateParams")
View popupView = layoutInflater.inflate(R.layout.menu_logout, null);
PopupWindow popupWindow = new PopupWindow(popupView, LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
popupWindow.setOutsideTouchable(true);
popupWindow.setFocusable(true);
popupWindow.setWidth(LinearLayout.LayoutParams.WRAP_CONTENT);
popupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
popupWindow.showAsDropDown(logoutParent);
TextView textView = popupView.findViewById(R.id.menu);
textView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
doLogoutWork();
}
});

Android - Trying to make Dialog with ImageView code

What I'm trying to do is when an Imageview item being preesed, then a Dialog will open up and show the inage in a large scale.
Now first of all this is the XML layout of the dialog -
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ImageView
android:id="#+id/imageView_large_pic"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/bkgnd_pressed" />
</LinearLayout>
Now the code to the Dialog is as follows -
Dialog settingsDialog = new Dialog(MainChat.this);
settingsDialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
settingsDialog.setContentView(getLayoutInflater().inflate(R.layout.image_large
, null));
ImageView ivLarge = (ImageView) findViewById(R.id.imageView_large_pic);
String pathpic = v.getTag().toString();
ivLarge.setImageURI(Uri.parse(pathpic));
settingsDialog.show();
Now I tried to dubuging this code, and it get stuck at this line - ivLarge.setImageURI(Uri.parse(pathpic));
The logcat gives me that this is java.lang.NullPointerException error.
Thanks for any kind of help
You are looking in the wrong place for the ImageView
ImageView ivLarge = (ImageView) findViewById(R.id.imageView_large_pic);
is looking in the layout you inflate in setContentView(). Instead, you need to look in the Dialog's layout. Try instead
ImageView ivLarge = (ImageView) settingsDialog .findViewById(R.id.imageView_large_pic);

Categories

Resources