How can I bypass parent's attributeset to child in android - java

I am creating compond view with imageView + TextView as ImageTextView as follow in xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="match_parent"
>
<Button android:id="#+id/btnView" android:layout_width="wrap_content" android:layout_height="wrap_content" />
<TextView android:id="#+id/txtView" android:layout_width="wrap_content" android:layout_height="wrap_content" />
</LinearLayout>
in usage, I want to use ImageTextView as follow:
<com.mypkg.MyClass.ImageTextView
android:layout_width="wrap_content"
android:layout_height="50dp"
android:text="text for textView" //used for textview
android:background="#drawable/background.png" //used for image view
/>
in imageTextViewConstructor, I want to bypass textSize, text, textColor and all textView's attributes to child txtView without layoutParams as following logic, how can I filter AttributeSet in java code.
public ImageTextView(Context context, AttributeSet attrs) {
super(context, attrs);
//------------------------------
// AttributeSet filteredAttrs= filterAttributeSet(attrs);
//I want to remove layoutparams and background from parent attributeset
//------------------------------
TextView mtxtView=(TextView)findViewByid(R.id.txtView);
mtxtView=new TextView(this,filteredAttrs);
}

TextView by itself can contain a Drawable on top, bottom, left (start) and/or right (end).
<TextView
...
android:drawablePadding="4dp"
android:drawableLeft="#drawable/my_drawable"/>
More on this topic here: http://antonioleiva.com/textview_power_drawables/

Related

How to limit the height of a RecyclerView inside a NestedScrollView

Within my current Android application, I have a screen that displays an android.support.v4.app.DialogFragment.
This DialogFragment view contains the following UI components
HEADING
== Sub Heading
== NestedScrollView
==== RecyclerView
==== RadioGroup
==== Spinner
==== EditText
==== Action Buttons
The DialogFragment is configured to be Full Screen using Style as follows:-
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(DialogFragment.STYLE_NO_TITLE, R.style.AppDialogTheme);
}
My dialog style is
<!-- Define your custom dialog theme here extending from base -->
<style name="AppDialogTheme" parent="Theme.AppCompat.Light.Dialog">
<!-- Define color properties as desired -->
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#000</item>
<item name="android:textColorHighlight">#color/background_url</item>
<item name="colorAccent">#color/dark_grey</item>
<item name="colorControlNormal">#color/colorPrimaryDark</item>
<!-- Define window properties as desired -->
<item name="android:windowNoTitle">true</item>
<item name="android:windowFullscreen">true</item>
<item name="android:windowBackground">#android:color/white</item>
<item name="android:windowIsFloating">true</item>
<item name="android:windowCloseOnTouchOutside">false</item>
</style>
The reason I employ a NestedScrollView is so that the View will work in both Portrait and Landscape mode.
I wish to limit the height of the RecyclerView
The closest I have got is using the layout below.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="#+id/headline_literal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:gravity="center"
android:padding="10dp"
android:text="Heading"
android:textSize="20sp"
android:textStyle="bold" />
<View
android:id="#+id/divider"
android:layout_width="fill_parent"
android:layout_height="2dp"
android:layout_marginTop="5dp"
android:background="#c0c0c0" />
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:weightSum="5"
android:orientation="vertical">
<TextView
android:id="#+id/sub_headline_literal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="10dp"
android:text="Some long texts having a long size so that it takes multiple lines in the view to replicate the real-life app use case. This is important to have 3-4 lines this textview so that we can see if the views are being populated correctly. Hope this sentence is long enough to replicate the real-life scenario of this TextView content. Thank you."
android:textSize="16sp"
android:textStyle="normal" />
<android.support.v7.widget.RecyclerView
android:id="#+id/dummy_rv"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_margin="10dp"
android:layout_marginStart="9dp"
android:layout_marginEnd="9dp"
android:layout_weight="1"
android:background="#drawable/rv_border"
android:fadingEdge="horizontal"
android:fadingEdgeLength="10dp"
android:padding="10dp"
android:requiresFadingEdge="vertical" />
<RadioGroup
android:id="#+id/myRadioGroup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="10dp"
android:checkedButton="#+id/sound">
<RadioButton
android:id="#+id/sound"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Sound" />
<RadioButton
android:id="#+id/vibration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Vibration" />
<RadioButton
android:id="#+id/silent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Silent" />
</RadioGroup>
<EditText
android:id="#+id/notes"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Notes" />
<LinearLayout
android:id="#+id/buttons"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="10dp">
<TextView
android:id="#+id/cancel_button"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="Cancel" />
<TextView
android:id="#+id/submit_button"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="Submit" />
</LinearLayout>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
</LinearLayout>
By using weightSum on the inner LinearLayout of the NestedScrollView I can limit the height of the Recyclerview. However the NestedScrollView height is far too large, with more than half its height being blank.
How can I limit the height of my RecyclerView and get NestedScrollView to wrap_content?
I've tried NestedScrollView with height wrap_content but this has no effect.
How can I achieve the desired UI? Thanks in advance!
Instead of having a NestedRecyclerView, I would like to suggest to have a header and a footer added to your RecyclerView which will nicely place the overall content as far as I have seen your layout. I want to provide you a link to my answer here where you can find how to add a footer and a header along with your RecyclerView.
Hence, I would like to suggest to create a view with headline_literal and the divider and use this as a header whereas the RadioGroup, EditText and the Button will be in the footer. Let me know if you face any problem with it.
I have tried to implement the behavior that you want by myself and let me know if the following implementation works for you. I have added this in Github as well.
Let us first declare an adapter for adding a header and a footer to the RecyclerView.
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import java.util.ArrayList;
public class RecyclerViewWithHeaderFooterAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final int FOOTER_VIEW = 1;
private static final int HEADER_VIEW = 2;
private ArrayList<String> data; // Take any list that matches your requirement.
private Context context;
// Define a constructor
public RecyclerViewWithHeaderFooterAdapter(Context context, ArrayList<String> data) {
this.context = context;
this.data = data;
}
// Define a ViewHolder for Header view
public class HeaderViewHolder extends ViewHolder {
public HeaderViewHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Do whatever you want on clicking the item
}
});
}
}
// Define a ViewHolder for Footer view
public class FooterViewHolder extends ViewHolder {
public FooterViewHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Do whatever you want on clicking the item
}
});
}
}
// Now define the ViewHolder for Normal list item
public class NormalViewHolder extends ViewHolder {
public NormalViewHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Do whatever you want on clicking the normal items
}
});
}
}
// And now in onCreateViewHolder, you have to pass the correct view
// while populating the list item.
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v;
if (viewType == FOOTER_VIEW) {
v = LayoutInflater.from(context).inflate(R.layout.list_item_footer, parent, false);
FooterViewHolder vh = new FooterViewHolder(v);
return vh;
} else if (viewType == HEADER_VIEW) {
v = LayoutInflater.from(context).inflate(R.layout.list_item_header, parent, false);
HeaderViewHolder vh = new HeaderViewHolder(v);
return vh;
}
// Otherwise populate normal views
v = LayoutInflater.from(context).inflate(R.layout.list_item_normal, parent, false);
NormalViewHolder vh = new NormalViewHolder(v);
return vh;
}
// Now bind the ViewHolder in onBindViewHolder
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
try {
if (holder instanceof NormalViewHolder) {
NormalViewHolder vh = (NormalViewHolder) holder;
vh.bindView(position);
} else if (holder instanceof FooterViewHolder) {
FooterViewHolder vh = (FooterViewHolder) holder;
} else if (holder instanceof HeaderViewHolder) {
HeaderViewHolder vh = (HeaderViewHolder) holder;
}
} catch (Exception e) {
e.printStackTrace();
}
}
// Now the critical part. You have return the exact item count of your list
// I've only one footer. So I returned data.size() + 1
// If you've multiple headers and footers, you've to return total count
// like, headers.size() + data.size() + footers.size()
#Override
public int getItemCount() {
if (data == null) {
return 0;
}
if (data.size() == 0) {
// Return 1 here to show nothing
return 1;
}
// Add extra view to show the header view
// Add another extra view to show the footer view
// So there are two extra views need to be populated
return data.size() + 2;
}
// Now define getItemViewType of your own.
#Override
public int getItemViewType(int position) {
if (position == 0) {
// This is where we'll add the header.
return HEADER_VIEW;
} else if (position == data.size() + 1) {
// This is where we'll add a footer.
return FOOTER_VIEW;
}
return super.getItemViewType(position);
}
// So you're done with adding a footer and its action on onClick.
// Now set the default ViewHolder for NormalViewHolder
public class ViewHolder extends RecyclerView.ViewHolder {
// Define elements of a row here
public ViewHolder(View itemView) {
super(itemView);
// Find view by ID and initialize here
}
public void bindView(int position) {
// bindView() method to implement actions
}
}
}
Now let us define the layouts one by one. Here is the list_item_normal.xml.
<?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="wrap_content">
<TextView
android:id="#+id/normal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="This is a text to be displayed in each item in the RecyclerView"
android:textSize="16sp"
android:textStyle="normal" />
</LinearLayout>
And the list_item_footer.xml should look like the following.
<?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="wrap_content"
android:layout_marginTop="16dp"
android:orientation="vertical">
<RadioGroup
android:id="#+id/myRadioGroup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="10dp"
android:checkedButton="#+id/sound">
<RadioButton
android:id="#+id/sound"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Sound" />
<RadioButton
android:id="#+id/vibration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Vibration" />
<RadioButton
android:id="#+id/silent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Silent" />
</RadioGroup>
<EditText
android:id="#+id/notes"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Notes" />
<LinearLayout
android:id="#+id/buttons"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="10dp">
<TextView
android:id="#+id/cancel_button"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="Cancel" />
<TextView
android:id="#+id/submit_button"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="Submit" />
</LinearLayout>
</LinearLayout>
Finally, the list_item_header.xml should have the following.
<?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="wrap_content">
<TextView
android:id="#+id/sub_headline_literal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="10dp"
android:text="Some long texts having a long size so that it takes multiple lines in the view to replicate the real-life app use case. This is important to have 3-4 lines this textview so that we can see if the views are being populated correctly. Hope this sentence is long enough to replicate the real-life scenario of this TextView content. Thank you."
android:textSize="16sp"
android:textStyle="normal" />
</LinearLayout>
Now you have divided the components of your original layout into parts. Hence the main layout should look like the following.
<?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="wrap_content"
android:orientation="vertical">
<TextView
android:id="#+id/headline_literal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:gravity="center"
android:padding="10dp"
android:text="Heading"
android:textSize="20sp"
android:textStyle="bold" />
<View
android:id="#+id/divider"
android:layout_width="fill_parent"
android:layout_height="2dp"
android:layout_marginTop="5dp"
android:background="#c0c0c0" />
<android.support.v7.widget.RecyclerView
android:id="#+id/dummy_rv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:padding="10dp" />
</LinearLayout>
Hence, I am sharing one sample Activity to run this code which will show the overall implementation.
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
private RecyclerView mRecyclerView;
private ArrayList<String> data = new ArrayList<String>();
private RecyclerViewWithHeaderFooterAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initializeData();
initializeRecyclerView();
}
private void initializeRecyclerView() {
mRecyclerView = findViewById(R.id.dummy_rv);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
adapter = new RecyclerViewWithHeaderFooterAdapter(this, data);
mRecyclerView.setAdapter(adapter);
}
private void initializeData() {
for (int i = 0; i < 10; i++) data.add("Position :" + i);
}
}
Hope that helps!
Customize Recycler view to set maxHeight.
public class MaxHeightRecyclerView extends RecyclerView {
private int mMaxHeight;
public MaxHeightRecyclerView(Context context) {
super(context);
}
public MaxHeightRecyclerView(Context context, AttributeSet attrs) {
super(context, attrs);
initialize(context, attrs);
}
public MaxHeightRecyclerView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initialize(context, attrs);
}
private void initialize(Context context, AttributeSet attrs) {
TypedArray arr = context.obtainStyledAttributes(attrs, R.styleable.MaxHeightScrollView);
mMaxHeight = arr.getLayoutDimension(R.styleable.MaxHeightScrollView_maxHeight, mMaxHeight);
arr.recycle();
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (mMaxHeight > 0) {
heightMeasureSpec = MeasureSpec.makeMeasureSpec(mMaxHeight, MeasureSpec.AT_MOST);
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
n attrs.xml
<declare-styleable name="MaxHeightScrollView">
<attr name="maxHeight" format="dimension" />
</declare-styleable>
set RecyclerView height wrap_content in xml and maxHeight to fixwidth in dp.
The RecyclerView will consume height wrap_content till fixWidth which you set, after reaching to maxHeight, the RecyclerView will scrollable.
If you also need to limit the size of your NestedScrollView by makeing a custom NestedScrollView:
public class CustomNestedScrollView extends NestedScrollView {
private int maxHeight;
private final int defaultHeight = 200;
public CustomNestedScrollView(Context context) {
super(context);
}
public CustomNestedScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
if (!isInEditMode()) {
init(context, attrs);
}
}
public CustomNestedScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
if (!isInEditMode()) {
init(context, attrs);
}
}
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
public CustomNestedScrollView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
if (!isInEditMode()) {
init(context, attrs);
}
}
private void init(Context context, AttributeSet attrs) {
if (attrs != null) {
TypedArray styledAttrs = context.obtainStyledAttributes(attrs, R.styleable.CustomNestedScrollView);
//200 is a defualt value
maxHeight = styledAttrs.getDimensionPixelSize(R.styleable.CustomNestedScrollView_maxHeight, defaultHeight);
styledAttrs.recycle();
}
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
heightMeasureSpec = MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
attr.xml
<declare-styleable name="CustomNestedScrollView">
<attr name="maxHeight" format="dimension" />
</declare-styleable>
example layout for custom NestedScrollView:
<your.package.CustomNestedScrollView
android:layout_weight="1"
app:maxHeight="90dp"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<!--Child view with RecyclerView here-->
</your.package.CustomNestedScrollView>
Along with this custom NestedScrollView if you apply the customization of your RecyclerView then it will work exactly how you want. I hope this helps!

Aligning the view to center

I want to place the two text horizontally at the center. It is very easy to put it directly in a layout.
But what i am trying to achieve is :
Testapplayout.xml: This is set as content view of the activity.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal" >
<com.example.testapp.Customlayout
android:id="#+id/custom"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginLeft="2dp"
android:layout_marginTop="2dp">
</com.example.testapp.Customlayout>
</LinearLayout>
class Customlayout
public class Customlayout extends LinearLayout {
public Customlayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public Customlayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public Customlayout(Context context) {
this(context, null, 0);
}
}
Now on the Testapplayout, customlayout, I am trying to inflate the layout to show the texts at the center:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center|bottom"
android:orientation="horizontal" >
<TextView
android:id="#+id/status_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="text1"
android:layout_gravity="center"
/>
<TextView
android:id="#+id/text2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/status_text"
/>
</LinearLayout>
This still comes at the
try
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/relative_layout"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<com.example.testapp.Customlayout
android:id="#+id/custom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true">
</com.example.testapp.Customlayout>
</RelativeLayout>

Custom Views, to insert them dynamically to Layout in Java

I can't stress that often enough, I am new to Android and Java in general :-)
And these xml layouts are giving me headaches.
The code what you see consist of two ImageViews and two TextViews inside a RelativeLayout, together they form a layout which for me works as a "custom button". When I copy and paste it inside my layout it works almost the way I want.
How can I use this part of xml-layout dynamically in my code whenever I need a button like that and still be able to change certain properties, like the text inside the textviews?
I hope you understand what I mean, my first language is not english.
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="match_parent" >
<ImageView
android:id="#+id/myImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginLeft="10dp"
android:src="#drawable/box" />
<TextView
android:id="#+id/myImageViewText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/myImageView"
android:layout_alignLeft="#+id/myImageView"
android:layout_alignRight="#+id/myImageView"
android:layout_alignTop="#+id/myImageView"
android:layout_margin="1dp"
android:gravity="center"
android:text="S-"
android:textColor="#000000"
android:textStyle="bold" />
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/myImageViewText"
android:layout_centerHorizontal="true"
android:layout_marginBottom="25dp"
android:text="your turn!"
android:textAppearance="?android:attr/textAppearanceSmall" />
<ImageView
android:id="#+id/imageView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/textView1"
android:layout_alignParentTop="true"
android:layout_marginBottom="15dp"
android:layout_marginTop="-10dp"
android:cropToPadding="false"
android:src="#drawable/icon" />
</RelativeLayout>
Ok to start extend your own view like this one:
I do have a Button made with an ImageView and a TextView in a LinearLayout designed in xml:
XML
<merge xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="#+id/ivImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:adjustViewBounds="true"
android:padding="3dp"
android:scaleType="fitStart" />
<TextView
android:id="#+id/tvText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="2dp"
android:layout_marginLeft="10dp"
android:ellipsize="end"
android:singleLine="true"
android:textColor="#android:color/white" />
</merge>
ViewObject called
ViewMenuButton
public class ViewMenuButton extends View{
private TextView tvText;
private ImageView ivImage;
public ViewMenuButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
public ViewMenuButton(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public ViewMenuButton(Context context) {
super(context);
init();
}
private void init() {
LayoutInflater inflater = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//here you can inflate a own XML for that View
inflater.inflate(R.layout.view_menubutton, this, true);
this.tvText= (TextView)this.findViewById(R.id.tvText);
this.ivImage = (ImageView)this.findViewById(R.id.ivImage);
}
public void setText(String text){
if(this.tvText != null){
tvText.setText(text);
}
}
//... and so on
}
Whenever you want to use it in your xml make sure to give the View the complete package like this:
Usage XML
<com.your.package.views.ViewMenuButton
android:id="#+id/menu_bt_local"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_marginTop="15dp"
android:layout_weight="1"
android:background="#drawable/action_button"
android:textSize="#dimen/text_cell" >
If you want to use it in a code just make it like this:
Usage JAVA
LinearLayout rootView =
(LinearLayout) findViewById(R.id.mainLayout); //Or sth like this
ViewMenuButton vmb = new ViewMenuButton(this);
rootView.add(vmb);
//or if you already have it in XML
ViewMenuButton vmb = (ViewMenuButton) findViewById(R.id.myVmbtID);
You can even go more in detail defining your own attributes to use in XML, like setting source of the Image, changing Text, changing TextColor etc pp Tutoiral
Create your custom View subclass. Inflate your layout in it's constructor, find necessary views there and create setters/getters of necessary properties. Then each time you need this custom button you'll be able to create it through code or xml using this subclass. If you need to be able to change some properties from xml too you may want to declare styleable attributes for your custom view. I think you can find lots of tutorials about how to create custom views.
Here's the common tutorial. Here you can read about custom attributes. And finally here is the best example of what I mentioned above.
You can inflate your layout and add it to another layout
RelativeLayout layout = new RelativeLayout(this);
View childButton = getLayoutInflater().inflate(R.layout.child_button, null);
layout.addView(childButton);
Now you can find the child views in the button layout as
TextView textViewInnerChild = (TextView)childButton.findViewById(R.Id. textInnerView):
Then you can change the value or properties of the inner child views
textViewInnerChild.set text("your text")

make a custom view from xml

I want to do a custom view coming from an XML.
Here's my XML :
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:id="#+id/movieTitle"
android:text="#string/movietitle"
android:textSize="35dp"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
/>
<com.galite.headliner.views.LoaderImageView
android:id="#+id/moviePoster"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/movieTitle"
android:layout_centerHorizontal="true"
android:layout_marginTop="20dp"
android:layout_marginBottom="20dp"
android:contentDescription="#string/poster"
/>
<TextView
android:id="#+id/movieDescription"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/description"
android:layout_below="#id/moviePoster"
android:gravity="center"
/>
</RelativeLayout>
And i want to inflate to a custom view because i need to use methods like onClick and everything.
Here's my constructor :
public MyView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.context = context;
initializeView();
}
public void initializeView(){
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.movie, null);
}
How can i make MyView equal to v ?
You'll have to attach the inflated view v to MyView like this:
v = inflater.inflate(R.layout.movie, this, true);
If you want that exact layout then make MyView to extend RelativeLayout and modify the xml layout like this:
<merge xmlns:android="http://schemas.android.com/apk/res/android" >
<TextView
android:id="#+id/movieTitle"
android:text="#string/movietitle"
android:textSize="35dp"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
/>
<com.galite.headliner.views.LoaderImageView
android:id="#+id/moviePoster"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/movieTitle"
android:layout_centerHorizontal="true"
android:layout_marginTop="20dp"
android:layout_marginBottom="20dp"
android:contentDescription="#string/poster"
/>
<TextView
android:id="#+id/movieDescription"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/description"
android:layout_below="#id/moviePoster"
android:gravity="center"
/>
</merge>

Checkbox is over text, how to add padding?

I have a listview with checkboxes:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="wrap_content">
<CheckBox android:layout_width="fill_parent"
android:layout_height="wrap_content" android:id="#+id/nomeAPP" style="?listItem" />
</LinearLayout>
But the problem is: checkboxes is over text (text is to much for the left)
How can I correct that?
How about putting android:paddingLeft="xdp" where is x is the number of dp that you will need to put in order to you text?
Putting padding will only shift text but not your "Tick-Button".
You may consider android:gravity property too if putting a hard-coded dp doesn't suit your need.
If your text is in the same layout of the checkbox, do it like this:
<CheckBox
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/nomeAPP"
style="?listItem"
android:layout_marginLeft="10dp" />
But if its not, do it like this:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="10dp">
<CheckBox
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/nomeAPP"
style="?listItem" />
</LinearLayout>
Obs: I've put margin and padding with left only for the example.
Let me know if you have more doubts. Thanks.
Here’s what I used for items in a list, each of which has text and a radio button. Note the layout_weight and layout_gravity settings:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:id="#+id/select_file_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:textSize="16sp"
android:layout_weight="100"
/>
<RadioButton
android:id="#+id/file_item_checked"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:textSize="16sp"
android:layout_gravity="right"
/>
</LinearLayout>
There are two ways to resolve this issue_
1 Building your own custom CheckBox Class by extending android.widget.CheckBox class. The Complete Custom code is as below_
public class CustomCheckBox extends CheckBox {
public CustomCheckBox(Context context) {
super(context);
}
public CustomCheckBox(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public CustomCheckBox(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
public int getCompoundPaddingLeft() {
final float scale = this.getResources().getDisplayMetrics().density;
/*add padding you needed so the text is not on top of the
* CheckBox.
*/
return (super.getCompoundPaddingLeft() + (int) (10.0f * scale + 0.5f));
}
}
2 Set Padding in Your Activity_
final float scale =this.getResources().getDisplayMetrics().density;
checkBox.setPadding(checkBox.getPaddingLeft() + (int)(10.0f * scale + 0.5f),
checkBox.getPaddingTop(),
checkBox.getPaddingRight(),
checkBox.getPaddingBottom());
I hope this will help all who have this issue... :)

Categories