I made a customed view by extending ViewGroup, my problems is:
when adding a child( addView(chileView) ) view into ViewGroup, if the child view is a inflated view, the child view will not show. but when the child view is hard-code view( like, btn = new Button(ctx) ), it will show!
The Code, not show:
public class EdgeSwiper extends ViewGroup{
public EdgeSwiper(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
public EdgeSwiper(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public EdgeSwiper(Context context) {
super(context);
init(context);
}
View v;
private void init(Context context) {
v = View.inflate(context,R.layout.aview,null);
this.addView(v);
}
#Override
protected void onLayout(boolean arg0, int a, int b, int c, int d) {
v.layout(a, b, c, d);
}
}
Related
I have a Custom View "CustomLayout" subclass of RelativeLayout.
public class CustomLayout extends RelativeLayout implements View.OnClickListener{
private String titleText;
private Context context;
private AttributeSet attrs;
private ImageView iv1,iv2;
private TextView title,tv2;
private TextView textView;
private Button button;
public CustomLayout(Context context) {
this(context, null);
}
public CustomLayout(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
this.attrs = attrs;
init();
}
public CustomLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.context = context;
this.attrs = attrs;
initAttributes(context,attrs,defStyle);
}
private void initAttributes(Context context, AttributeSet attrs, int defStyleAttr) {
// declare styleable here to programatically set custom view style attributes
final int[] styleable = new int[] {
android.R.attr.src,
android.R.attr.textAppearance,
android.R.attr.text,
android.R.attr.textSize
};
Arrays.sort(styleable);
TypedArray a = context.obtainStyledAttributes(attrs, styleable, defStyleAttr,0);
...
}
I don't know how to set the properties pro-grammatically by passing arguments in the last constructor ,which takes three arguments, from my Activity. I know to do it from layout.xml file as shown in code below.Please help
<com.example.customview.CustomLayout
android:id="#+id/view1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?android:selectableItemBackground"
app:titleText="HappyTrips Editors"
app:descriptText="#string/content"
app:titleTextColor="#FF0000"
app:descriptTextColor="#0000FF"
app:titleTextSize="8sp"
app:descriptTextSize="6sp"
app:bgColor="#FFFF00"/>
In my ListAdapter
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View result=convertView;
if (convertView==null){
result=inflater.inflate(R.layout.layout_list_items,null);
CustomLayout object = (CustomLayout)result.findViewById(R.id.view1);
How to pass arguments containing AttributeSet in CustomLayout constructor from here
in layout.xml you can user style,it will work or
CustomLayout object=new CustomLayout(new ContextThemeWrapper(this,R.style,customStyle));
I am trying to subclass TextInputLayout, in a CustomTextInputLayout. This is the code:
public class CustomTextInputLayout extends TextInputLayout {
public CustomTextInputLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomTextInputLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public CustomTextInputLayout(Context context) {
super(context);
}
public View getComponent(){
return this.getChildAt(0);
}
public void setHint(String hint){
super.setHint(hint);
}
}
I am using it to wrap another custom component, with a button and an EditText:
public class ComponentesSeleccion extends RelativeLayout {
private EditText editText;
private Button button;
public ComponentesSeleccion(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public ComponentesSeleccion(Context context) {
super(context);
inicializar();
}
public ComponentesSeleccion(Context context, AttributeSet attrs) {
super(context, attrs);
inicializar();
}
private void inicializar() {
String infService = Context.LAYOUT_INFLATER_SERVICE;
LayoutInflater li =
(LayoutInflater)getContext().getSystemService(infService);
li.inflate(R.layout.seleccionlayout, this, true);
editText=(EditText)findViewById(R.id.editText);
button=(Button)findViewById(R.id.button2);
}
public Button getButton() {
return button;
}
public EditText getEditText() {
return editText;
}
public void setInputType(int type){
editText.setInputType(type);
}
public void setImagen(Drawable drawable){
button.setBackgroundDrawable(drawable);
}
}
With this, I am not able to do in my code:
CustomTextInputLayout ctil=(CustomTextInputLayout)view.findViewById(R.id.ctil);
ctil.setHint(“a hint");
No exception, no errors, but the hint is not drawn. i can set the normal hint on the EditText, but I want the animated hint of the TextInputLayout.
How could I get it working?
Thank you.
I have a class which extends LinearLayout. This class has a method called addSubview and the warning message "Method 'actionXYZ' is never used" shows, but the method have public modifier!
Furthermore, this method does not appear when this class is instantiated in a activity, for example.
Why?
public class dummyLayout extends RelativeLayout {
LayoutInflater mInflater;
RelativeLayout rootItem;
public dummyLayout(Context context) {
super(context);
init(context);
}
public dummyLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public dummyLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
private void init(Context ctx) {
mInflater = LayoutInflater.from(ctx);
rootItem = (RelativeLayout) mInflater.inflate(R.layout.dummyLayout, this, true);
}
public void addSubView(View v) {
rootItem.addView(v);
}
}
I am extending a frame layout
and when in the constructor (after it loaded the view from xml) i call getChildCount()
I get 0. How to fix this ?
public class DisabledFrameLayout extends FrameLayout {
public DisabledFrameLayout(Context context) {
super(context);
init(context, null,0);
}
public DisabledFrameLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context,attrs,defStyle);
}
public DisabledFrameLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init(context,attrs,0);
}
private void init(Context context, AttributeSet attrs, int defStyle) {
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.DisabledFrameLayout, 0, 0);
if(a.hasValue(R.styleable.DisabledFrameLayout_disable_descendants)) {
boolean disable = a.getBoolean(R.styleable.DisabledFrameLayout_disable_descendants, false);
if(disable) {
disableDescendants(this);
}
}
a.recycle();
}
private void disableDescendants(ViewGroup v) {
for (int i=0; i<v.getChildCount();i++) {
if(v.getChildAt(i) instanceof ViewGroup) {
disableDescendants((ViewGroup)v.getChildAt(i));
}
v.setEnabled(false);
v.setFocusable(false);
v.setFocusableInTouchMode(false);
}
}
}
xml
<com.lenabru.DisabledFrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:disable_descendants="true"
>
<include
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
layout="#layout/fragment_p" />
</com.lenabru.DisabledFrameLayout>
In state of constructing your FrameLayout, children are still not fully attached to the view. So, calling getChildCount() will return you 0.
If you want to iterate over child views and update them, do it inside onLayout() or onMeasure().
Refs:
http://blog.denevell.org/android-custom-views-onlayout-onmeasure.html
ViewGroup - check this example code.
I'm trying something like this
public class CustomViewSubclass extends HorizontalScrollView{
private LinearLayout layout;
public CustomViewSubclass(Context context) {
this(context,null,0);
}
public CustomViewSubclass(Context context, AttributeSet attrs) {
this(context,attr,0);
}
public CustomViewSubclass(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
layout = new LinearLayout(context);
}
// This is called from the `Activity`
public void startAsyncTask() { // code }
// This method is called in the `onPostExecute()` of an `AsyncTask` subclass
public void doSomething(Context context) {
ImageView image = ImageView(context);
layout.addView(image); // NullPointerException here, layout seems to be null
}
but it seems that layout on doSomething() is null. How is that even possible? I'm initializing it on the constructor... and I never re-initialize it again;
I'm adding my custom view via XML
<com.mypackage.CustomViewSubclass
android:layout_width="wrap_content"
android:layout_width="match_parent" />
Ok I fixed it, it was an stupid mistake made by me:
I used super() on the 3 methods, instead of using this().
public CustomViewSubclass(Context context) {
super(context,null,0);
}
public CustomViewSubclass(Context context, AttributeSet attrs) {
super(context,attr,0);
}
public CustomViewSubclass(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
layout = new LinearLayout(context);
}
Solution:
public CustomViewSubclass(Context context) {
this(context,null,0);
}
public CustomViewSubclass(Context context, AttributeSet attrs) {
this(context,attr,0);
}
public CustomViewSubclass(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
layout = new LinearLayout(context);
}