How do I make a ChipGroup to act like a radioGroup? - java

How do I make a ChipGroup to act like a radioButton where one item can be selected at a time while changing the background color.
I saw this link for something like this but it did not help me since because am using a layoutInflater to show my chip item.
firebaseFirestore.collection("Categories").addSnapshotListener((queryDocumentSnapshots, e) -> {
for (DocumentChange doc: queryDocumentSnapshots.getDocumentChanges()){
if (doc.getType() == DocumentChange.Type.ADDED){
Categories categories = doc.getDocument().toObject(Categories.class);
post_list.add(categories);
Chip chip = (Chip) getLayoutInflater().inflate(R.layout.chip_item_layout, chipGroup, false);
chip.setText(categories.getTitle());
chipGroup.addView(chip);
chipGroup.setOnCheckedChangeListener((chipGroup, id) -> {
Chip chip2 = ((Chip) chipGroup.getChildAt(chipGroup.getCheckedChipId()));
if (chip2 != null) {
for (int i = 0; i < chipGroup.getChildCount(); ++i) {
chipGroup.getChildAt(i).setClickable(true);
chip2.setChipBackgroundColorResource(R.color.customOrange);
}
chip2.setClickable(false);
}
});
}
}
});

In your ChipGroup use the app:singleSelection="true" attribute. In this way the ChipGroup can be configured to only allow a single chip to be checked at a time.
<com.google.android.material.chip.ChipGroup
app:singleSelection="true"
..>
Then you can set a selector color using the app:chipBackgroundColor attribute in your layout chip_item_layout.xml.
Something like:
<com.google.android.material.chip.Chip
style="#style/Widget.MaterialComponents.Chip.Choice"
app:chipBackgroundColor="#color/chip_background_color"
..>
Pay attention to style="#style/Widget.MaterialComponents.Chip.Choice" because it defines the chip as android:checkable="true".
The chip_background_color is a selector where you can define your favorite colors in the different states. It is the default selector, you can change it:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 24% opacity -->
<item android:alpha="0.24" android:color="?attr/colorPrimary" android:state_enabled="true" android:state_selected="true"/>
<item android:alpha="0.24" android:color="?attr/colorPrimary" android:state_enabled="true" android:state_checked="true"/>
<!-- 12% of 87% opacity -->
<item android:alpha="0.10" android:color="?attr/colorOnSurface" android:state_enabled="true"/>
<item android:alpha="0.12" android:color="?attr/colorOnSurface"/>
</selector>
The selected chip is define by the color in your case is the first line (android:state_selected="true").
If you would like to do it programmatically just use (not in the OnCheckedChangeListener) the setChipBackgroundColorResource method.
chip.setChipBackgroundColorResource(R.color.chip_background_color);
Also if you want to require at least one selection you can use the app:selectionRequired attribute. This attribute requires the 1.2.0 (starting from 1.2.0-alpha02)

Related

Fully Transparent Navigation Bar and Status Bar

I want to make a fully transparent status bar and navigation bar like Google Play did. When I use window settings to achieve it, the keyboard covers EditText.
When this code used EditText covered by Keyboard Input:
getWindow().setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
Also this code doesn't make it fully transparent, it just makes it translucent
getWindow().setNavigationBarColor(Color.TRANSPARENT)
or this
<item name="android:navigationBarColor">#android:color/transparent</item>
I need a window like this:
What you need is something like this:
class Utils {
static void enableInmersiveMode(Activity act, boolean drawBehindNavBar) {
View rootView = act.getWindow().getDecorView().getRootView();
int uiFlags = rootView.getSystemUiVisibility();
int flags =0;
if(drawBehindNavBar) { flags = View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION; }
flags = flags | uiFlags | View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEEN;
rootView.setSystemUiVisibility(flags);
}
}
And in your onCreate of your activity:
#Override
void onCreate(Bundle b) {
Utils.enableInmersiveMode(this, true);
super.onCreate(b);
// setContentView and the rest of your code here...
}
Take in mind that afterwards views will go behind the system UI and you'll need to dynamically add padding to the first and last Views so the user can interact with them.
Hopefully, you can try this in your-main-path/res/values/styles.xml
This is for transparent Status Bar and Navigation Bar in any android devices.
<item name="android:statusBarColor">#android:color/transparent</item>
<item name="android:navigationBarColor">#android:color/transparent</item>
One more thing if you want to try transparency and float the to the bar you can use this but the background of Navigation Bar will reduce 50% of transparency.
<item name="android:windowTranslucentNavigation">true</item>
When you want to unset the TranslucentNavigation float, this one can fit the screen between Status Bar and Navigation Bar
<item name="android:fitsSystemWindows">true</item>

How to remove the green bar on a android app in android studio

Like the title, I am wondering how to get rid of the green bar at the top so that it matches the background of the activity. I have no idea where to look I've had a look in the manifest and haven't found anything.
What do I do so that it matches the background of the activity?
Note. Different activities have different backgrounds, so is there a way that I just match the activity it is on?
The green bar is called Status bar, and to hide it in activity call below method in onCreate()
void hideStatusBar() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN;
getWindow().getDecorView().setSystemUiVisibility(uiOptions);
} else {
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
}
And to hide it in a fragment, call it in onCreateView()
void hideStatusBar() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN;
requireActivity().getWindow().getDecorView().setSystemUiVisibility(uiOptions);
} else {
requireActivity().getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
}
You can change status bar color using this extension function, call this function from Activity just passing the color
fun AppCompatActivity.changeStatusBarColor(#ColorRes color: Int) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
window.statusBarColor = ContextCompat.getColor(this, color)
}
}
go to following path:
app->res->values->styles
and here in style tag three item tags are available, in that colour of first and last item keep same.
then app status bar and action bar colour display same.
Example:
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here.
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
-->
<item name="colorPrimary">#FFA500</item>
<item name="colorPrimaryDark">#FFA500</item>
</style>

Android: checking a view's background

I have 3 buttons, all of them have the same background drawable by default (subject_button)
What I want to do:
When I click one button his background changes ( to clicked_subject), all the others remain with the default background, if I click one button after clicking another, the button I just clicked changes his background while the previous one gets back to the initial background, allowing only one button to have the clicked_subject background, if the diffrent button gets clicked again his background goes back to the initial one, leting all the buttons with the initial background.
The problem:
If I click the diffrent button, his background remains the same instead of changing back to the initial one.
My logic:
theButton1.setBackgroundResource(R.drawable.subject_button);
theButton1.setOnClickListener(this);
//same for other 2
#Override
public void onClick(View v) {
if (v.getBackground() == ContextCompat.getDrawable(this, R.drawable.subject_button)) {
theButton1.setBackgroundResource(R.drawable.subject_button);
theButton2.setBackgroundResource(R.drawable.subject_button);
theButton3.setBackgroundResource(R.drawable.subject_button);
v.setBackgroundResource(R.drawable.clicked_subject);
} else {
v.setBackgroundResource(R.drawable.subject_button);
}
Why is this happening?
You can do this:
private final List<Button> mButtons = new ArrayList<>();
// somewhere in your code
mButtons.add(mButton1);
mButtons.add(mButton2);
mButtons.add(mButton3);
mButton1.setOnClickListener(mClickListener);
mButton2.setOnClickListener(mClickListener);
mButton3.setOnClickListener(mClickListener);
private final View.OnClickListener mClickListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
for (Button button : mButtons) {
if (button == v) {
// set selected background
} else {
// set not selected backround
}
}
}
};
If you define a stateful drawable for your buttons, then you can simply change the onclick to this:
private final View.OnClickListener mClickListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
for (Button button : mButtons) {
button.setSelected(v == button);
}
}
};
For changing background color/image based on the particular event(focus, press, normal), you need to define a button selector file and implement it as background for button. For example button_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:drawable="#drawable/your_image1" /> <!-- pressed -->
<item android:state_focused="true"
android:drawable="#drawable/your_image2" /> <!-- focused -->
android:drawable="#drawable/your_image3" <!-- default -->
</selector>
then just apply it as :
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawable="#drawable/button_selector.xml" />
I solved it by instead of changing only the background color on clicking the button, I also change the textColor, then I can check the textColor with if (((Button) v).getCurrentTextColor() == Color.WHITE)
"Pressed", "selected", "disabled" and such are View states. As such they're supposed to be handled automatically by Android and not by your click listeners.
This is achieved using SateLists, which control the look your Views sould have depending on which state(s) they're in. So you can easily set subject_button as the unpressed state, clicked_subject as the pressed state, and let Android take care of actually switching between them.
Full explanation: https://developer.android.com/guide/topics/resources/drawable-resource.html#StateList

Android Fragment Share Element Transition with Hide and Show

I am trying to make Share Element Transition for RecyclerView element , using the image as the share element.
I am able to make other transition work except the Share Element Transition.
my guess is that the problem is on in Transition.hide and transition.Show.
other that that i am stuck. please help :)
Here is the method that handles the transition
public void goToProduct(ProductItem current) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Transition changeTransform = TransitionInflater.from(this).
inflateTransition(R.transition.change_image_transform);
Transition explodeTransform = TransitionInflater.from(this).
inflateTransition(android.R.transition.explode);
productListFragment.setSharedElementReturnTransition(changeTransform);
productListFragment.setExitTransition(explodeTransform);
productPageFragment.setSharedElementEnterTransition(changeTransform);
productPageFragment.setEnterTransition(explodeTransform);
isProductPageOpenedFromCart = false;
isProductPageOpenedFromList = false;
ImageView listImage = (ImageView) findViewById(R.id.listImg1);
ImageView pageImage = (ImageView) findViewById(R.id.pageImg);
FragmentTransaction transaction = manager.beginTransaction();
transaction.hide(productListFragment)
.addToBackStack("transaction")
.addSharedElement(listImage, "MyTransition");
if (isCartOpen) {
CartFragment cartFragment = (CartFragment) manager.findFragmentByTag(CART_FRAGMENT_TAG);
transaction.remove(cartFragment);
isCartOpen = false;
isProductPageOpenedFromCart = true;
} else {
isProductPageOpenedFromList = true;
}
productPageFragment.setProduct(current);
transaction.show(productPageFragment).addToBackStack("transaction")
.addSharedElement(pageImage, "MyTransition");;
transaction.commit();
}
else {
the transition folder file is named change_image_transform and contains:
<?xml version="1.0" encoding="utf-8"?>
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
<changeTransform/>
<changeImageTransform/>
</transitionSet>
I also did use android:transitionName="MyTransition" on boath images.
And here are lines of code added to style.xml
<item name="android:windowContentTransitions">true</item>
<item name="android:windowEnterTransition">#transition/change_image_transform</item>
<item name="android:windowExitTransition">#transition/change_image_transform</item>
<item name="android:windowSharedElementEnterTransition">#transition/change_image_transform</item>
<item name="android:windowSharedElementExitTransition">#transition/change_image_transform</item>
In RecyclerView you propably have many views with id R.id.listImg1 You have to in adapter set sharedView setTransitionName programatycally for example you can use your product id for creating transition name. And when you creating second details fragment you can pass by bundle transition name to that gragment. In onCrete you can set image transitionname to the same like before.
Or you can create:
public interface IRecyclerClikListener {
public void onItemClik(int pos,Object obj,View view);
}
Add this listener to your recycler. To the view you pass a refrence to clikced row. If you have reference to cliked view you can set transition name to image belongs to this view. Dont forget to set the same transition name in second fragment.

How to adjust size of second image from setImageResource()

I am new to java/android and am making a test app. It has ImageButtons that when clicked switch to a different image temporarily. The originals are cropped using
android:adjustViewBounds="true"
android:scaleType="centerCrop"
in the activity_main.xml
The problem is the second image isnt cropped and is therefore too big for the button. DOes anyone know how I can fix this? HEres a an example of one of the buttons:
public void onClick(View v) {
//switch to second img
butt2.setImageResource(R.drawable.newimg);
//switch back to first after pause
new Handler().postDelayed(new Runnable() {
public void run() {
butt2.setImageResource(R.drawable.orig);
}
}, 500L);
}
});
I have used the following
int normal[] = { R.drawable.num0, R.drawable.num1, R.drawable.num2,
R.drawable.num3, R.drawable.num4, R.drawable.num5,
R.drawable.num6, R.drawable.num7, R.drawable.num8,
R.drawable.num9, R.drawable.del, R.drawable.go };
int pressed[] = { R.drawable.num0_clicked, R.drawable.num1_clicked,
R.drawable.num2_clicked, R.drawable.num3_clicked,
R.drawable.num4_clicked, R.drawable.num5_clicked,
R.drawable.num6_clicked, R.drawable.num7_clicked,
R.drawable.num8_clicked, R.drawable.num9_clicked,
R.drawable.del_clicked, R.drawable.go_clicked };
StateListDrawable sld;
for (int i = 0; i < 12; i++) {
sld = new StateListDrawable();
sld.addState(new int[] { android.R.attr.state_pressed },
getResources().getDrawable(pressed[i]));
sld.addState(new int[] {}, getResources().getDrawable(normal[i]));
btns[i].setImageDrawable(sld);
}
There's another way to attempt this thing , if you want like when you click the button its background should change and when you release it , background gets to previous one .
This can be achieved as follows
Now in your main.xml file that you want to show as an activity and where you have declared the button tag , add a statement
android:background="#drawable/customDefaultBackground"
and it will be like
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/customDefaultBackground" />
Now add an xml file of selector tag type and name it as customDefaultBackground.xml, open that file and add following to its contents :-
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_pressed="true" android:drawable="#drawable/onPressBackground" ></item>
<item android:drawable="#drawable/defaultBackground"></item>
</selector>
Item tag with android:state_pressed set to true , denotes that when a user clicks on a button and keep it pressed the backgroundOnPressed version will be displayed else it will show default background.

Categories