I have this code:
holder.ImageMain.setMaxHeight(holder.ImageMain.getWidth());
My intention is to have a square imageview if the image is big and horizontal. the code will set a height that is the same as the width.
But for some reason it's not working. The imageView has been long and horizontal.
Do you have any idea what's wrong with it?
You can try to use
android:adjustViewBounds= "true"
or to a more controled case, use instead a custom ImageView that in the onMeasure method adjust it size like you want. For example here are an example to create a 16/9 ImageView
public class SixteenNineImageView extends ImageView {
public SixteenNineImageView(Context context) {
super(context);
}
public SixteenNineImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SixteenNineImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
public SixteenNineImageView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
final int width = getMeasuredWidth();
final int height = (width * 9) / 16;
setMeasuredDimension(width, height);
}
}
Related
I see a class that use this class for show images in square.
i can't understand what is this class? have any feature for show images in square?
this code used in layout xml file instead of RelativeLayout
class SquareLayout extends RelativeLayout {
public SquareLayout(Context context) {
super(context);
}
public SquareLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SquareLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
public SquareLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// Set a square layout.
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
}
The important line is super.onMeasure(widthMeasureSpec, widthMeasureSpec);. As you can see, the height is replace with the width. So you have width x width instead of width x height. That is a square. onMeasure is used to tell the system the requested Area of the view. Hope it helps
I am trying to create a textview that will always be squared so I have implemented this custom class.
public class SquareTextView extends TextView {
public SquareTextView(Context context) {
super(context);
}
public SquareTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SquareTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int max = Math.max(getMeasuredWidth(), getMeasuredHeight());
setMeasuredDimension(max, max);
}
}
Here is an example layout that illustrates the problem:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="8dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="8dp">
<com.mypackage.SquareTextView
android:layout_width="wrap_content"
android:layout_height="50dp"
android:layout_gravity="right|top"
android:background="#000"
android:gravity="center"
android:padding="4dp"
android:text="1"
android:textColor="#FFF"/>
</LinearLayout>
Here is an image of this
This works great in getting the view squared, however, it seems like the gravity gets messed up. With this, the text seems to always be in the top left corner. How can I have a TextView that will always be squared but still keep the gravity or at least be able to center the text?
EDIT: After some testing I have noticed that if you set the width or height to a specific dp size the gravity seems to be working again. So it probably has to do with the WRAP_CONTENT attribute. Will that be handled in another way in the onmeasure method that could cause my own method to not work as expected?
Hope you have already got the answer by now. If not, you can use this:
public class TextAlphaSquareTextView extends AppCompatTextView {
private int mTextAlpha = 0;
private boolean isSquare = false;
public TextAlphaSquareTextView(Context context) {
super(context);
init(null);
}
public TextAlphaSquareTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init(attrs);
}
public TextAlphaSquareTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(attrs);
}
private void init(AttributeSet attrs) {
if (attrs == null) {
} else {
TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.TextAlphaSquareTextView);
mTextAlpha = a.getInteger(R.styleable.TextAlphaSquareTextView_textAlpha, 100);
isSquare = a.getBoolean(R.styleable.TextAlphaSquareTextView_squareMode, false);
a.recycle();
if(mTextAlpha < 0 || mTextAlpha > 100)
throw new IllegalArgumentException("Alpha range should be b/w 0 to 100 (in percentage)");
else {
setAlphaOnTextColor();
}
}
setText(getText());
}
void setAlphaOnTextColor() {
int alpha = ((255 * mTextAlpha) / 100);
setTextColor(getTextColors().withAlpha(alpha));
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (isSquare) {
int width = this.getMeasuredWidth();
int height = this.getMeasuredHeight();
int size = Math.max(width, height);
int widthSpec = MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY);
int heightSpec = MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY);
super.onMeasure(widthSpec, heightSpec);
}
}
}
you need to call super.onMeasure() again with EXACT spec and the calculated size, since setMeasureDimension() seems to be ignoring the gravity.
Before RecyclerView, I used this class to make grid's height dependant on it's childs(so it works fine in scrollview):
public class FullHeightGridView extends GridView
{
public FullHeightGridView(Context context)
{
super(context);
}
public FullHeightGridView(Context context, AttributeSet attrs)
{
super(context, attrs);
}
public FullHeightGridView(Context context, AttributeSet attrs,
int defStyle)
{
super(context, attrs, defStyle);
}
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
// Calculate entire height by providing a very large height hint.
// View.MEASURED_SIZE_MASK represents the largest height possible.
int expandSpec = MeasureSpec.makeMeasureSpec(MEASURED_SIZE_MASK,
MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
ViewGroup.LayoutParams params = getLayoutParams();
params.height = getMeasuredHeight();
}
}
How can I modify GridLayoutManager to behave in the same way?
I have a GridView and I'm trying to display two columns. I want to fix my image size to my GridView. Locally, my code was working, but when I load my JSON it the "auto fit" stops working.
The code is:
public class SquareImageView extends ImageView{
public SquareImageView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public SquareImageView(Context context, AttributeSet attrs)
{
super(context, attrs);
}
public SquareImageView(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(getMeasuredWidth(), getMeasuredWidth()); //Snap to width
}
}
Use Below CustomImageView Class and you xml should be as follows
public class CustomImageView extends ImageView {
public CustomImageView(Context context) {
super(context);
}
public CustomImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, widthMeasureSpec); // This is the key that will make the height equivalent to its width
}
}
And your Xml should be like this
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.yourpackage.CustomImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop" />
</LinearLayout>
I am creating a custom imageview and I am trying to find the height of the parent. The only detail I know about the parent is that it would potentially scroll. The reason I need the parent's height is because I am trying to figure out the imageview's position on the screen. I have made an equation that works for accurately calculating its position, but it only works when I manually enter in the parents height. Is there any way to retrieve this information or is there another way to get my imageview's position on the screen every time it changes?
Try this way
public class MyImageView extends ImageView {
int parentHeight;
int parentWidth;
public MyImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public MyImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyImageView(Context context) {
super(context);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if(((View)this.getParent()).getMeasuredWidth()!=0){
parentHeight = ((View)this.getParent()).getMeasuredHeight();
parentWidth = ((View)this.getParent()).getMeasuredWidth();
}
}
}