i tried to create custom linear layout that have dynamic height and width = height. The custom layout is fine, but the child view not showing at my custom linear layout. i tried some way to fix it, but still cant solve it.
public class CustomLinearLayout extends LinearLayout {
public CustomLinearLayout(Context context) {
super(context);
}
public CustomLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int height = MeasureSpec.getSize(heightMeasureSpec);
setMeasuredDimension(height, height);
}
}
this is the xml that contain my custom linear layout. the child view not showing.
<com.example.admin.antriclient.CustomLinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:autofit="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="100dp"
android:layout_height="100dp"
android:background="#drawable/bg_nomor_antrian"
android:padding="10dp"
>
<me.grantland.widget.AutofitTextView
android:id="#+id/service_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Teller"
android:textColor="#color/white"
android:textStyle="bold"
android:gravity="center_horizontal"
android:singleLine="false"
autofit:minTextSize="12sp"
/>
<me.grantland.widget.AutofitTextView
android:id="#+id/nomor_antrian"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="T21"
android:textSize="50sp"
android:textColor="#color/white"
android:textStyle="bold"
android:gravity="center_horizontal"
android:singleLine="true"
autofit:minTextSize="12sp"
/>
</com.example.admin.antriclient.CustomLinearLayout>
thanks in advance
My problem is because i didnt call the super.onMeasure() method. Thanks to Mike M.
my class should be like this
public class CustomLinearLayout extends LinearLayout {
public CustomLinearLayout(Context context) {
super(context);
}
public CustomLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(heightMeasureSpec,heightMeasureSpec);
//int height = MeasureSpec.getSize(heightMeasureSpec);
//setMeasuredDimension(height, height);
}
}
For me I had to add a LayoutInflater for it to show
public class SidebarLayout extends LinearLayout {
private static final String TAG = "SidebarLayout";
public SidebarLayout(Context context) {
super(context);
}
public SidebarLayout(Context context, #Nullable AttributeSet attrs) {
super(context, attrs);
LayoutInflater.from(context).inflate(R.layout.sidebar, this);
}
public SidebarLayout(Context context, #Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
}
<com.example.a3danimationtester.SidebarLayout
android:id="#+id/layout_sidebar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/layout_topbar" />
Related
In my app I use a GridView but my values for each cells are not same size, when I put my values in GridView, it automatically set a size for all cells(I think it consider first cell height for all cells), can you tell me how can I fix that?
GridView Adapter:
You should try to use custom view your row Item in Gridview
public class SquareRelativeLayout extends RelativeLayout {
public SquareRelativeLayout(Context context) {
super(context);
}
public SquareRelativeLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SquareRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
if (widthMeasureSpec < heightMeasureSpec)
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
else
super.onMeasure(heightMeasureSpec, heightMeasureSpec);
}
}
In GridView row XML
<SquareRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<ImageView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/image"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:adjustViewBounds="true"
android:contentDescription="#string/descr_image"
android:scaleType="centerCrop" />
</SquareRelativeLayout>
Hope this helps you.
I suggest please use RecyclerView with StaggeredGridLayoutManager, Throw this you can get layout same which you draw upside,
This is the link which will help you:
https://android--code.blogspot.in/2015/12/android-recyclerview.html
I got a bunch of form controls that all show an Icon to the left, like so:
For this I have this code:
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginRight="8dp"
android:layout_weight="1"
android:orientation="horizontal">
<ImageView
android:layout_width="wrap_content"
android:layout_height="#dimen/icon_edittext_height"
android:layout_gravity="top"
android:layout_marginRight="#dimen/icon_edittext_marginRight"
android:layout_marginTop="#dimen/icon_edittext_margintop"
android:src="#drawable/ic_location_city_black_24dp"/>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.design.widget.TextInputLayout
android:id="#+id/create.data.city.layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<AutoCompleteTextView
android:id="#+id/create.data.city"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/create_event_city"
android:imeOptions="actionNext"
android:inputType="textCapSentences"
android:maxLines="1"
/>
</android.support.design.widget.TextInputLayout>
</FrameLayout>
</LinearLayout>
Now because I have around 20 controls, I dont want to repeat the:
<LinearLayout>
<ImageView/>
<FrameLayout>
...content....
</FrameLayout>
</LinearLayout>
schema 20 times, but I would like to do something like this:
<MycustomLayout>
<EditText .../>
</MycustomLayout>
<MycustomLayout>
<Spinner ... />
</MycustomLayout>
So basically I want to create a custom Layout that extends Linear, and I want to be able to use it in the same way that I use LinearLayout, while having an icon prepended at all times.
You can try using include tag in your layout to include the part which is repeating. Or if that doesn't work you can try something like this:
public class CustomControl extends LinearLayout {
public CustomControl (Context context, AttributeSet attrs) {
super(context, attrs);
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.custom_layout, this);
}
}
Where custom_layout is the layout for you custom view.
Then you can just do in your xml:
<CustomControl />
UPD:
In order to add child views in xml just override onFinishInflate and add views like this:
protected void onFinishInflate() {
View[] children = detachChildren();
for (int i = 0; i < children.length; i++)
this.addView(children[i]);
}
No need to add too much layouts. Just try to use this...
<android.support.design.widget.TextInputLayout
android:id="#+id/create.data.city.layout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<AutoCompleteTextView
android:id="#+id/create.data.city"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="City"
android:drawableLeft="#drawable/ic_location_city_black_24dp"
android:drawablePadding="5dp"
android:imeOptions="actionNext"
android:inputType="textCapSentences"
android:maxLines="1" />
</android.support.design.widget.TextInputLayout>
Solved it myself like so:
public class IconFieldLinearLayout extends LinearLayout {
private Drawable mDefaultDrawable;
public IconFieldLinearLayout(Context context) {
super(context);
init(context, null);
}
public IconFieldLinearLayout(Context context, #Nullable AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public IconFieldLinearLayout(Context context, #Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
public IconFieldLinearLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(context, attrs);
}
private void init(Context context, AttributeSet attrs) {
this.setOrientation(HORIZONTAL);
mDefaultDrawable = getResources().getDrawable(R.drawable.tv_avatar_default);
initAttr(context, attrs);
}
private void initAttr(Context context, AttributeSet attrs) {
if (attrs != null) {
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.IconFieldLinearLayout, 0, 0);
Drawable icon = a.getDrawable(R.styleable.IconFieldLinearLayout_icon);
a.recycle();
initIcon(context, icon);
}
else {
initIcon(context, mDefaultDrawable);
}
}
private void initIcon(Context context, Drawable icon) {
ImageView imageView = new ImageView(context);
imageView.setColorFilter(ContextCompat.getColor(context, R.color.colorAccent));
int dimension = getResources().getDimensionPixelSize(R.dimen.icon_edittext_height);
int marginRight = getResources().getDimensionPixelSize(R.dimen.icon_edittext_marginRight);
int marginTop = getResources().getDimensionPixelSize(R.dimen.icon_edittext_margintop);
LinearLayout.LayoutParams layoutParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, dimension);
layoutParams.gravity = Gravity.TOP;
layoutParams.setMargins(0, marginTop, marginRight, 0);
imageView.setImageDrawable(icon);
addView(imageView, layoutParams);
}
}
Did not really need to put the FrameLayout in there.
I try to align spinner and edit text by baseline, but it doesn't work:
It start happen after update support library dependency from 24.1.1 to 24.2.1 (support-v4, appcompat-v7, design).
This is my xml code:
<RelativeLayout
android:id="#+id/email_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<android.support.v7.widget.AppCompatSpinner
android:id="#+id/spinner"
style="#style/MailSpinner"
android:layout_width="120dp"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:dropDownWidth="wrap_content" />
<android.support.design.widget.TextInputLayout
android:id="#+id/text_input_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_alignBaseline="#id/spinner"
android:layout_toStartOf="#id/spinner"
android:baselineAlignedChildIndex="0">
<android.support.v7.widget.AppCompatEditText
android:id="#+id/edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="E-mail"
android:ellipsize="end"
android:imeOptions="actionNext"
android:inputType="textEmailAddress"
android:textSize="16sp"/>
</android.support.design.widget.TextInputLayout>
</RelativeLayout>
MailSpinner style:
<style name="MailSpinner" parent="Widget.AppCompat.Spinner.Underlined">
<item name="android:background">#drawable/spinner_textfield_background</item>
<item name="backgroundTint">#color/spinner_tint</item>
<item name="backgroundTintMode">src_atop</item>
</style>
Essentially the TextInputLayout isn't providing a baseline value to it's parent. We need to pipe the correct baseline of the EditText by extending TextInputLayout. This works for me, however, I'm not sure if the baseline would change due to other events from the TextInputLayout.
public class CTextInputLayout extends TextInputLayout {
public CTextInputLayout(Context context) {
super(context);
}
public CTextInputLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CTextInputLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#Override
public int getBaseline()
{
EditText editText = getEditText();
return editText.getPaddingTop() + editText.getBaseline();
}
}
I think this version is better when hint label is floating
public class CTextInputLayout extends TextInputLayout {
public CTextInputLayout(Context context) {
super(context);
}
public CTextInputLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CTextInputLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#Override
public int getBaseline() {
EditText editText = getEditText();
return getMeasuredHeight() - (editText.getMeasuredHeight() - editText.getBaseline());
}
}
Here's a version which aligns correctly when the TextInputLayout error text is set:
public class BaselineTextInputLayout extends TextInputLayout {
public BaselineTextInputLayout(Context context) {
super(context);
}
public BaselineTextInputLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public BaselineTextInputLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#Override
public int getBaseline() {
EditText editText = getEditText();
if (editText == null) { return 0; }
return editText.getTop() + editText.getBaseline();
}
}
I create an autoCompleteTextView as below Layout and Java class :
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/autoCompleteTextViewGroup"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:animateLayoutChanges="true"
android:minHeight="#dimen/component_height">
<android.support.design.widget.TextInputLayout
android:id="#+id/textInputLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:animateLayoutChanges="true">
<AutoCompleteTextView
android:id="#+id/autoCompleteTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:completionThreshold="1"
android:singleLine="true" />
</android.support.design.widget.TextInputLayout>
<android.support.v4.widget.ContentLoadingProgressBar
android:id="#+id/progressBar"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center_vertical"
android:indeterminate="true"
android:indeterminateDrawable="#anim/anim_indeterminate_mini"
android:interpolator="#anim/anim_progress_interpolator"
android:visibility="visible" />
</FrameLayout>
and Java class is :
public class MAutoCompleteText extends LinearLayout {
AutoCompleteTextView autoCompleteTextView;
ContentLoadingProgressBar progressBar;
TextInputLayout textInputLayout;
ViewGroup autoCompleteTextViewGroup;
public MAutoCompleteText(Context context) {
super(context);
init(context);
}
public MAutoCompleteText(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public MAutoCompleteText(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
#TargetApi(21)
public MAutoCompleteText(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(context);
}
private void init(Context context) {
inflate(context, R.layout.layout_auto_complete_text, this);
autoCompleteTextViewGroup = (ViewGroup) findViewById(R.id.autoCompleteTextViewGroup);
textInputLayout = (TextInputLayout) findViewById(R.id.textInputLayout);
autoCompleteTextView = (AutoCompleteTextView) findViewById(R.id.autoCompleteTextView);
progressBar = (ContentLoadingProgressBar) findViewById(R.id.progressBar);
}
public void setAdapter(ArrayAdapter<String> adapter) {
autoCompleteTextView.setAdapter(adapter);
}
public String getText() {
return autoCompleteTextView.getText().toString();
}
public void setErrorEnabled(boolean status) {
textInputLayout.setErrorEnabled(status);
}
public void setError(int errorId) {
textInputLayout.setError(getContext().getString(errorId));
}
public int getVisibility() {
return autoCompleteTextViewGroup.getVisibility();
}
public void setVisibility(int visibility) {
autoCompleteTextViewGroup.setVisibility(visibility);
autoCompleteTextViewGroup.setMinimumHeight(R.dimen.component_height);
}
public void setProgressBarVisibility(int visibility) {
progressBar.setVisibility(visibility);
}
public MAutoCompleteText setHint(int hintId) {
autoCompleteTextView.setHint(hintId);
return this;
}
public void setImeOption(int imeOption) {
autoCompleteTextView.setImeOptions(imeOption);
}
}
Everything work OK. I setVisibility(GONE) and my component hide from UI,
but when I use setVisibility(VISIBLE) doesn't happen any thing !!!!
How can I display my component programmatically?
I found answer of my problem , at least it works now ... :)
I change setVisibility to below code :
public void setVisibility(int visibility) {
autoCompleteTextViewGroup.setVisibility(visibility);
if (visibility == View.VISIBLE) {
textInputLayout.setVisibility(visibility);
autoCompleteTextView.setVisibility(visibility);
progressBar.setVisibility(visibility);
requestLayout();
}
}
In fact requestLayout(); reDraw layout of my component on UI again and it`s appear correctly .
For Android Image View .. how to scale 1081*373 Image Button to match the width of Image View and be fixed height ??
i tried match parent for width if image button but it' details not appear ... look like Zoomed image ?? and can't use Gravity ??
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/mainempty"
/>
<ImageButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="#drawable/about"
/>
Try it!
public class MyBanner extends ImageView {
public MyBanner(Context context) {
super(context);
}
public MyBanner(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyBanner(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = width * 373 / 1081;
setMeasuredDimension(width, height);
}
}
in xml
<your.package.MyBanner
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/about"/>