I am using a custom Group indicator as shown in the code below. Now if I leave the default I can use setBounds perfectly, but when using my custom image which is the same dimensions and setup as the same .9 patch file it is always half off screen. No matter what values I use for setBounds()
Drawable plus = (Drawable) getResources().getDrawable(R.drawable.expander_group);
getExpandableListView().setGroupIndicator(plus);
Display newDisplay = getWindowManager().getDefaultDisplay();
int width = newDisplay.getWidth();
getExpandableListView().setIndicatorBounds(0,0);
XML expander_group
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_expanded="true"
android:drawable="#drawable/minus" />
<item
android:drawable="#drawable/plus" />
</selector>
EDIT:
Interestingly. I have copied the exact xml and image files from the standard Android files. And when I use the above method to define it the exact same thing happens! So it is not the xml or image files that are causing the issue I think.
Related
I need to set the height of this RelativeLayout to match the height of the Soft Keyboard. To make sure the EditText appears just above the keyboard.
Is it possible to set some kind of Listener to detect every time the keyboard height changes?
The proper way to do this would be to set soft input to match your needs.
try following for a fragment put this line in your fragment's onCreate method:
getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
You can set multiple modes with a single line like
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE|WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
And if you are working in an activity you can just adjust it in your android manifest file for each activity
<activity
android:name=".SomeActivity"
android:windowSoftInputMode="adjustResize" />
or
android:windowSoftInputMode="adjustPan|adjustResize"
Check which settings suits your needs better between adjustPan, adjustUnspesified, adjustResize or some other soft input options.
I figured out a solution that seems to work fine. With only 1 problem. For some reason the Status Bar turns white with this piece of code.. Any idea why?
ViewCompat.setOnApplyWindowInsetsListener(this.getWindow().getDecorView(), (v, insets) -> {
int keyboardHeight = insets.getInsets(WindowInsetsCompat.Type.ime()).bottom;
//Code logic
return insets;
});
How I set the Status Bar color:
<style name="AppTheme.GuessWord">
<item name="colorPrimaryDark">#color/primaryColor</item>
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
I have a Widget for my Android App. On this Widget there is a button. The user can freely choose the color of the button. So I also have to set the colors for the different button states dynamically.
Normally, I would do something like this:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/colorButtonRedTransparentPressed"
android:state_pressed="true" />
<item android:drawable="#color/colorButtonRedTransparentPressed"
android:state_focused="true" />
<item android:drawable="#color/colorButtonRedTransparentNotPressed" />
</selector>
As mentioned, I have to do this dynamically because the user is free to choose the color:
StateListDrawable drawable = new StateListDrawable();
drawable.addState(new int[] {}, new ColorDrawable(Color.parseColor(customButton.getColorHex())));
drawable.addState(new int[] { android.R.attr.state_pressed }, new ColorDrawable(Color.parseColor("#0000")));
The challenge:
The button is on a Widget. So i cannot just simply call:
myButton.setBackground(drawable);
I need to call something like this:
remoteView.setInt(R.id.button_fixedvalue, "setBackground", drawable)
But the function expects an integer and I don't have one.
Does anyone have a different approach?
Option 1
If there is a limited number of colors that the user can choose from, you could create a selector resource for each color option and then use the `setInt()` method to assign the resource ID that corresponds to the selected color.
Option 2
If by "freely choose" you mean that the user can select any possible color - or at least from a very large number - option 1 won't work of course.
Depending on what your drawable exactly looks like, you could try this instead:
Create only a single selector resource.
Use an ImageView for your button.
Apply the color as a tint to the ImageView using the ImageView.setColorFilter() method.
That would look something like this:
remoteView.setInt(R.id.button_id, "setColorFilter", Color.parseColor("#0000"))
I have a problem with Android Glide. I am trying to quickly swap my image, they just become all placeholder size, and my placeholder image is very low size. So what I need to do?
Maybe I need to check if it's loaded or something, but I don't know how.
Glide.with(this)
.load(quest.get(id).getImage())
.placeholder(R.drawable.load)
.fitCenter()
.crossFade()
.into(imageView);
According to this issue on Glide GitHub page you can fix it with adding following line to your request of Glide:
.dontAnimate()
That would make your full load line:
Glide.with(context)
.load("http://lorempixel.com/150/150")
.placeholder(R.drawable.no_image)
.override(100, 100)
.dontAnimate()
.into(imageView);
I do it like mentioned below:
The idea is to set the scale type to as required by the place holder initially & attach listener to change the scale type again to as required by the downloaded image after the image is downloaded.
//ivBuilderLogo = Target ImageView
//Set the scale type to as required by your place holder
//ScaleType.CENTER_INSIDE will maintain aspect ration and fit the placeholder inside the image view
holder.ivBuilderLogo.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
//AnimationDrawable is required when you are using transition drawables
//You can directly send resource id to glide if your placeholder is static
//However if you are using GIFs, it is better to create a transition drawable in xml
//& use it as shown in this example
AnimationDrawable animationDrawable;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
animationDrawable=(AnimationDrawable)context.getDrawable(R.drawable.anim_image_placeholder);
else
animationDrawable=(AnimationDrawable)context.getResources().getDrawable(R.drawable.anim_image_placeholder);
animationDrawable.start();
Glide.with(context).load(logo_url)
.placeholder(animationDrawable)
.listener(new RequestListener<String, GlideDrawable>() {
#Override
public boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource)
{
return false;
}
//This is invoked when your image is downloaded and is ready
//to be loaded to the image view
#Override
public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource)
{
//This is used to remove the placeholder image from your ImageView
//and load the downloaded image with desired scale-type(FIT_XY in this case)
//Changing the scale type from 'CENTER_INSIDE' to 'FIT_XY'
//will stretch the placeholder for a (very) short duration,
//till the downloaded image is loaded
//setImageResource(0) removes the placeholder from the image-view
//before setting the scale type to FIT_XY and ensures that the UX
//is not spoiled, even for a (very) short duration
holder.ivBuilderLogo.setImageResource(0);
holder.ivBuilderLogo.setScaleType(ImageView.ScaleType.FIT_XY);
return false;
}
})
.into( holder.ivBuilderLogo);
My transition drawable (R.drawable.anim_image_placeholder) :
(not required if using a static image)
<?xml version="1.0" encoding="utf-8"?>
<animation-list
xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item android:drawable="#drawable/loading_frame1" android:duration="100" />
<!--<item android:drawable="#drawable/loading_frame2" android:duration="100" />-->
<item android:drawable="#drawable/loading_frame3" android:duration="100" />
<!--<item android:drawable="#drawable/loading_frame4" android:duration="100" />-->
<item android:drawable="#drawable/loading_frame5" android:duration="100" />
<!--<item android:drawable="#drawable/loading_frame6" android:duration="100" />-->
<item android:drawable="#drawable/loading_frame7" android:duration="100" />
<!--<item android:drawable="#drawable/loading_frame8" android:duration="100" />-->
<item android:drawable="#drawable/loading_frame9" android:duration="100" />
<!--<item android:drawable="#drawable/loading_frame10" android:duration="100" />-->
</animation-list>
What I did in this regard was to use override() to enforce image size. If you have a gridview and you need to have two images in each row, this is how you find the screen size in pixels to calculate the correct width and height of the image:
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
Point size = new Point();
display.getSize(size);
placeholderWidth = size.x / 2 ;
placeholderHeight = size.x * 3 / 2 ; // based on the image's height to width ratio
Once the desired width and height for each image is in hand, it's easy to use override:
Glide.with(context)
.load(url)
.placeholder(R.drawable.loading)
.override(placeholderWidth,placeholderHeight)
.into(viewHolder.imageViewHolder);
If I correctly understand your problem, you need to load images, but they must have width and height bigger than your placeholder image.
To solve your problem you first should read documentation for Glide.
I can't see your ImageView definition in the xml file, but i think that you use wrap_content attribute for width and height.
If I am right there is your bottleneck.
Before image loading is started, Glide gets exact ImageView width and height. After that it loads image from the network and at the same time resize it according to the one of the ImageView attributes(width or height).
Thats why you get small images after loading.
To solve your problem just set width or height of the ImageView in value that you expect to see. Other side of the image will be automatically calculated by the Glide logic.
If someone came here from search just like me and wondering how to change Glide's placeholder size but remain image size original (in my case placeholder was to big), here's the solution. Wrap your placeholder drawable in another drawable with tag inset:
<?xml version="1.0" encoding="utf-8"?>
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:inset="20%">
<animated-rotate
android:drawable="#drawable/ic_loading"
android:pivotX="50%"
android:pivotY="50%" />
</inset>
Note that you can replace animated-rotate with any of allowed tags. Also, you can set different insets for each side of drawable (insetTop, insetBottom and so on), and specify insets in dp or %
Background
Lollipop introduces a new way to transition between activities (links here, here, here and here) .
The problem
They said on one of the videos (here) that I can choose exactly how each view will transition, but I can't find how to do it. The only thing I've found is how to set it for all views, except for the "hero" view (which you choose how to transition it to the new activity and back).
For example, let's take the Google Now app, which has this screen:
when you click on the editText, the bottom cards have the "explode" effect, but everything darkens and the imageView behind the editText fade out.
The editText is probably the "hero" view, which transitions between the activities, and because it's on the same location on the screen, this probably doesn't have any visual effect for the user.
What I've tried
I've tried to mimic what Google now did, but as I've written, the imageView also has the "explode" effect, so it goes to the bottom, behind the listView, which is a weird effect (since it gets cropped while animating). I'd prefer it to either animate to a different direction, or just fade out.
Here's a sample code of the transition I'm using:
final Intent intent = new Intent(activity, SearchActivity.class);
ViewCompat.setTransitionName(viewToTransitionFromAndTo, VIEW_TO_TRANSITION_TO);
final ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(activity,
viewToTransitionFromAndTo, VIEW_TO_TRANSITION_TO);
ActivityCompat.startActivityForResult(activity, intent, requestCode, options.toBundle());
in the theme of the activity that starts the other activity, I have this:
<style name="AppTheme.transition" parent="#style/AppTheme">
<!-- transition support -->
<item name="android:windowContentTransitions" tools:targetApi="21">true</item>
<item name="android:windowActivityTransitions" tools:targetApi="21">true</item>
<item name="android:windowEnterTransition" tools:targetApi="21">#transition/explode</item>
<item name="android:windowExitTransition" tools:targetApi="21">#transition/explode</item>
<item name="android:windowSharedElementEnterTransition" tools:targetApi="21">#transition/move_image</item>
<item name="android:windowSharedElementExitTransition" tools:targetApi="21">#transition/move_image</item>
<item name="android:windowAllowReturnTransitionOverlap" tools:targetApi="21">true</item>
<item name="android:windowAllowEnterTransitionOverlap" tools:targetApi="21">false</item>
</style>
and the transition files are:
explode.xml
<?xml version="1.0" encoding="utf-8"?>
<explode />
move_image.xml
<?xml version="1.0" encoding="utf-8"?>
<transitionSet>
<changeBounds />
<changeImageTransform />
</transitionSet>
The question
How can I choose what each view will do upon transition, instead of just saying everything to have the same effect (except for the "hero" view) ?
For example, is it possible to choose "explode" transition for all views except for the "hero" view , and a view that will have a different transition (fade out/in, for example) ?
Please show an example of how to do it. You can use the code I've written above if needed.
Use a TransitionSet and add/exclude certain targets using Transition#addTarget() and Transition#excludeTarget(). For example, let's say you have two views and you want each of them to slide off the screen in different directions. You could create such a transition using the following code:
TransitionSet set = new TransitionSet();
Transition slideUp = new Slide(Gravity.UP);
slideUp.addTarget(view1);
set.addTransition(slideUp);
Transition slideDown = new Slide(Gravity.DOWN);
slideDown.addTarget(view2);
set.addTransition(slideDown);
TransitionSet extends Transition, so the resulting set object can then be used as the window content transition, which will play the two slide transitions simultaneously in parallel.
I create a TableLayout dynamically via code and want to set a margin between columns. The only type of content my TableRows contain are TextViews.
My intention was to put a simple android:layout_marginRight on each TextView. But I want to definde this via xml instead of code.
What I tried:
The code:
txtView.setTextAppearance(context, R.style.TableTextView);
txtView.setText(content);
tableRow.addView(txtView);
The XML
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="TableTextView">
<item name="android:textAppearance">?android:attr/textAppearanceLarge</item>
<item name="android:textStyle">bold</item>
<item name="android:layout_marginRight">5dip</item>
</style>
</resources>
What happens:
The layout_marginRight set in the XML does not work, but the textAppearance and textStyle set in the XML do work. I assume the setTextAppearance-method is the wrong way for assigning a margin to a TextView? It would be really nice if I could do this via XML (like I tried it above) instead of Java-code.
Thank you!
This happens because you're setting the style to the text itself and not the TextView element.
You should set the element style in the XML. it's possible to achive this from the code as well, but i think it's best to do that in the XML Layout file.
Something like :
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
style="#style/mTableTextView" />
About setting that from code, i'm not an expert but i understood you can inflate it somehow.
Check out This, And This questions.
You want to give margin between columns
android.widget.TableRow.LayoutParams param = new android.widget.TableRow.LayoutParams();
param.rightMargin = Converter.dpToPixel(10, getContext()); // right-margin = 10dp
button.setLayoutParams(param);
// Converter:
private static Float scale;
public static int dpToPixel(int dp, Context context) {
if (scale == null)
scale = context.getResources().getDisplayMetrics().density;
return (int) ((float) dp * scale);
}
you can set different of value table parameters.