android cast to custom View : ClassCastException: android.widget.LinearLayout - android

i get ClassCastException: android.widget.LinearLayout
i'm trying to catch the fact that view (Lineralayout) has the elements of listview (one of it's children) in it.
customview:
public class MasterView extends View {
public boolean done=false;
public MasterView(Context context) {
super(context);
}
public MasterView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MasterView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
protected void onFinishInflate() {
// TODO Auto-generated method stub
done=true;
super.onFinishInflate();
}
}
the way I call it:
View master = (View)findViewById(R.id.master);
MasterView master2 = (MasterView)master; //exception
the xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/master"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<RelativeLayout
android:id="#+id/cnt"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="0.03" >
</RelativeLayout>
</LinearLayout>
I inflate cnt with the list

The R.id.master element in your xml is not of type MasterView. Change your xml to something like:
<yourpackage.MasterView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/master"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<RelativeLayout
android:id="#+id/cnt"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="0.03" >
</RelativeLayout>
</yourpackage.MasterView>

Related

Multiple layouts inside the single viewStub

I have an item which has apple, pear and lemon. I made separate layouts for apples, pears and lemons.
I want to get the layout of that element if any element is selected. I tried that put the correct layout to viewStub according to selected layout with inflate() function. But the performance of defining layouts with inflate() each time was exhausting and sometimes caused incorrect work.
Please help me.
My general view codes:
public class MyView extends RelativeLayout {
private ViewStub viewStub;
private int lemon = 1, apple = 2, pear = 3;
public MyView(Context context) {
this(context, null);
}
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
protected void onFinishInflate() {
super.onFinishInflate();
this.viewStub = ViewUtil.findById(this, R.id.view_stub);
}
public void bindElements(int type){
if (type == lemon) {castLemon(); return;}
if (type == apple ) {castApple(); return;}
if (type == pear) {castPear(); return;}
public void castLemon() {
viewStub.setLayoutResource(R.layout.lemon_item);
LemonView lemonView = (LemonView) viewStub.inflate();
}
}
public void castApple() {
viewStub.setLayoutResource(R.layout.apple_item);
AppleView appleView = (AppleView) viewStub.inflate();
}
}
public void castPear() {
viewStub.setLayoutResource(R.layout.pear_item);
PearView pearView = (PearView) viewStub.inflate();
}
}
}
My general view xml:
<com.android.android.MyView
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:id="#+id/myView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<LinearLayout android:id="#+id/bodyLinear"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<ViewStub
android:id="#+id/view_stub"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start|center_vertical"
android:gravity="start|center_vertical"
android:paddingBottom="5dp"/>
</LinearLayout>
</com.android.android.MyView>
LemonView.java:
public class LemonView extends FrameLayout {
private ImageView imageView;
public LemonView(Context context) {
this(context, null);
}
public LemonView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public LemonView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
inflate(context, R.layout.lemon_view, this);
imageView = findViewById(R.id.image);
}
lemon_view:
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.android.android.LemonView">
<ImageView
android:id="#+id/image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:adjustViewBounds="true"
android:contentDescription="#null"
android:gravity="center"
android:scaleType="centerCrop"/>
</merge>
lemon_item xml:
<?xml version="1.0" encoding="utf-8"?>
<com.android.android.LemonView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/lemon_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
Create all the layouts at once, then just show / hide the needed layout variant with .setVisibility(View.VISIBLE) / .setVisibility(View.GONE).

Why the error 'The following classes could not be instantiated in custom views' is showing in android?

In my app, I am creating views with extending relative class(For text view i am extending native textview in my java class) because I want to give custom font and don't want to apply font in every individual text view. For this I am using below code
public class LoyaltyTextView extends TextView {
private final static String DROID_SANS = "droid_sans";
public LoyaltyTextView(Context context) {
super(context);
}
public LoyaltyTextView(Context context, AttributeSet attrs) {
super(context, attrs);
parseAttributes(context, attrs);
}
public LoyaltyTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
parseAttributes(context, attrs);
}
private void parseAttributes(Context context, AttributeSet attrs) {
TypedArray values = context.obtainStyledAttributes(attrs,R.styleable.LoyaltyTextView);
String typeface = values.getString(R.styleable.LoyaltyTextView_customTypeFace);
if(typeface.equalsIgnoreCase(DROID_SANS)) {
setTypeface(Typeface.createFromAsset(context.getAssets(), "DroidSans.ttf"));
}
values.recycle();
}
}
and i am using above custom control in xml as mentioned below
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/bg_splash">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_above="#+id/tv_logo"
android:layout_centerHorizontal="true"
android:src="#drawable/logo_m" />
<customconstrols.LoyaltyTextView
android:id="#+id/tv_logo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="20dp"
android:text="#string/loyalty_logo"
android:textSize="#dimen/logo_text_size"
android:textStyle="bold"
app:customTypeFace="DROID_SANS" />
</RelativeLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.customconstrols.LoyaltyTextView
android:layout_width="150dp"
android:layout_height="wrap_content"
android:text="#string/login"
/>
</RelativeLayout>
</LinearLayout>
</LinearLayout>
</RelativeLayout>
but when I use simple text views (as native android widget) it works fine but when i use above custom control preview section starts giving me error as mentioned in picture
I have tried number of solution which were mentioned in different post like clear cache/invalidate option and refresh layout and cleaning project and rebuilding it but nothing worked for me. Anything I am missing?
Replace your code as following line in your xml
xmlns:font="http://schemas.android.com/apk/res-auto"
Run your app,It will work fine.
public class MyFontTextView extends TextView {
private Typeface typeface;
public MyFontTextView(Context context) {
super(context);
}
public MyFontTextView(Context context, AttributeSet attrs) {
super(context, attrs);
setCustomFont(context, attrs);
}
public MyFontTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setCustomFont(context, attrs);
}
private void setCustomFont(Context ctx, AttributeSet attrs) {
TypedArray a = ctx.obtainStyledAttributes(attrs, R.styleable.app);
String customFont = a.getString(R.styleable.app_customFont);
setCustomFont(ctx, customFont);
a.recycle();
}
private boolean setCustomFont(Context ctx, String asset) {
try {
if (typeface == null) {
typeface = Typeface.createFromAsset(ctx.getAssets(),
"fonts/OpenSans-Regular.ttf");
}
} catch (Exception e) {
AndyUtils.generateLog("Exception in component"+e);
return false;
}
setTypeface(typeface);
return true;
}
}
And in values -> attr.xml
<declare-styleable name="app">
<attr name="customFont" format="string" />
</declare-styleable>
Try this

ListView collapse in CustomScrollView

Hello I am new in Android development, and I've read various threads which talked about the fact that a ListView should not be inside a Scrollview and need to wrap in linear or relative layout.
But I have a this layout
<com.itmind.spac.spacapp.custom_extends.CustomScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/scrollViewreceipt"
>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<include
android:id="#+id/include1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
layout="#layout/toolbar" />
<Spinner
android:id="#+id/customers_spinner"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:theme="#android:style/Theme.Holo.Light.DarkActionBar"
/>
<Spinner
android:id="#+id/venues_spinner"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:theme="#android:style/Theme.Holo.Light.DarkActionBar"
/>
<Spinner
android:id="#+id/workgroup_spinner"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:theme="#android:style/Theme.Holo.Light.DarkActionBar"
/>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minHeight="150dp">
<ListView
android:id="#+id/activityList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="15dp"
android:minHeight="150dp"
/>
</LinearLayout >
<android.gesture.GestureOverlayView
android:id="#+id/signaturePad"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_weight="5"
android:background="#d3d3d3"
android:eventsInterceptionEnabled="true"
android:fadeEnabled="false"
android:gestureColor="#333"
android:gestureStrokeLengthThreshold="0.1"
android:gestureStrokeType="multiple"
android:fadeOffset="5000"
android:orientation="vertical" >
</android.gesture.GestureOverlayView>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="testImage"
android:text="testami"/>
</LinearLayout>
And this is my custoScrollView
public class CustomScrollView extends ScrollView {
private boolean enableScrolling = true;
public boolean isEnableScrolling() {
return enableScrolling;
}
public void setEnableScrolling(boolean enableScrolling) {
this.enableScrolling = enableScrolling;
}
public CustomScrollView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public CustomScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomScrollView(Context context) {
super(context);
}
#Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (isEnableScrolling()) {
return super.onInterceptTouchEvent(ev);
} else {
return false;
}
}
#Override
public boolean onTouchEvent(MotionEvent ev) {
if (isEnableScrolling()) {
return super.onTouchEvent(ev);
} else {
return false;
}
}
}
I need customclass scroll view beacause I can set enable scroll when i touch on
so in my activity that implements GestureOverlayView.OnGestureListener I have:
#Override
public void onGestureStarted(GestureOverlayView overlay, MotionEvent event) {
myScrollView.setEnableScrolling(false);
}
#Override
public void onGestureEnded(GestureOverlayView overlay, MotionEvent event) {
myScrollView.setEnableScrolling(true);
}
So many elements and I need to scrollView for view all elements.
Inside my scrollView I have a listView that I populate with data retrieve from db.
My problem is that my Listview collapse, that shows one line and I see and scroll in one row.
I tried with min-height but doesn't work, and if I put a layout height in Listview, I cant scroll this list.
How can I do this?
I would a list View in a long page so I have to use scrollview or are there solutions?
Below given custom ListView class will make height of your Listview based on its content inside ScrollView. Use it instead of ListView in your xml-layout file same way you use your CustomScrollView.
public class CustomListView extends ListView {
// private boolean expanded;
public CustomListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomListView(Context context) {
super(context);
}
public CustomListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
}
}
Hope this will help you.
Note :- As per this link of Android developer website, We should never use a ScrollView with a ListView, because ListView takes care of its own vertical scrolling.

Creating a view that holds unknown number of layout children

I want to create a ViewGroup that contains unknown number of other views as children (like LinearLayout):
<Wizard id=... width=... height=...>
<WizardStep id=... nextButtonOnClick=... preButtonOnClick=... >
<LinearLayout ...>
...
</LinearLayout>
</WIzardStep>
<WizardStep id=... nextButtonOnClick=... preButtonOnClick=... >
<RelativeLayout ...>
...
</RelativeLayout>
</WIzardStep>
<WizardStep id=... nextButtonOnClick=... preButtonOnClick=... >
...
</WIzardStep>
</Wizard>
Here Wizard and WizardStep both are ViewGroup. I don't have clue where to start. Extending ViewGroup and required functionality is all I need to do? I will appreciate any help, document, blog, etc.
This can be achieved through a ViewFlipper. If you wanted to do it programmatically, this would be a start. (NOTE: I didn't test this code, just wrote it off the top of my head)
The xml layout flip.xml
<?xml version="1.0" encoding="utf-8"?>
<ViewFlipper xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/flippy"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</ViewFlipper>
And the activity would look something like this
public class MainActivity extends Activity{
ViewFlipper flip;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.flip);
flip = (ViewFlipper)findViewById(R.id.flip);
}
private void addViews(){
//This is where you would determine which views to add
flip.add(****** your view 1 *****)
flip.add(****** your view 2 *****)
}
You would add views whenever you were parsing the data to create them dynamically.
Then to navigate your views you can use:
flip.showNext()
flip.showPrevious()
There are more complicated things you can do with it, but that should give you the basics.
My Solution:
WizardView class:
public class WizardView extends RelativeLayout {
Context context;
private final String KEY_LAST_STEP_PASSED = "KEY_LAST_STEP_PASSED";
private final String KEY_WIZARD_FINISHED = "KEY_WIZARD_FINISHED";
private int currentStep;
private boolean isWizardFinished;
private SharedPreferences preferences;
public WizardView(Context context) {
super(context);
this.context = context;
}
public WizardView(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
}
public WizardView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.context = context;
}
public void startWizard() {
preferences = context.getSharedPreferences("wizard_pref", Context.MODE_PRIVATE);
isWizardFinished = preferences.getBoolean(KEY_WIZARD_FINISHED, false);
if (!isWizardFinished) {
currentStep = preferences.getInt(KEY_LAST_STEP_PASSED, 0);
// Make all Steps (except current step) GONE
int count = getChildCount();
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
if (currentStep == i) {
child.setVisibility(View.VISIBLE);
} else {
child.setVisibility(View.GONE);
}
}
}
}
public void nextStep() {
int count = getChildCount();
getChildAt(currentStep).setVisibility(View.GONE);
if (currentStep < (count - 1)) {
currentStep++;
preferences.edit().putInt(KEY_LAST_STEP_PASSED, currentStep).commit();
getChildAt(currentStep).setVisibility(View.VISIBLE);
} else {
finishWizard();
}
}
public void previousStep() {
if (currentStep > 0) {
getChildAt(currentStep).setVisibility(View.GONE);
currentStep--;
preferences.edit().putInt(KEY_LAST_STEP_PASSED, currentStep).commit();
getChildAt(currentStep).setVisibility(View.VISIBLE);
}
}
public void finishWizard() {
isWizardFinished = true;
preferences.edit().putBoolean(KEY_WIZARD_FINISHED, true).commit();
setVisibility(View.GONE);
}
}
WizardStep Class:
public class WizardStepView extends RelativeLayout {
public WizardStepView(Context context) {
super(context);
}
public WizardStepView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public WizardStepView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
}
Sample layout file with Wizard:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<com.example.wizardtest.WizardView
android:id="#+id/wizard"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<com.example.wizardtest.WizardStepView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone" >
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:onClick="wizardNext"
android:text="Next(2)" />
</com.example.wizardtest.WizardStepView>
<com.example.wizardtest.WizardStepView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone" >
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:onClick="wizardNext"
android:text="Next(3)" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:onClick="wizardPrevious"
android:text="Previous(1)" />
</com.example.wizardtest.WizardStepView>
<com.example.wizardtest.WizardStepView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone" >
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:onClick="wizardPrevious"
android:text="Previous(2)" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:onClick="wizardNext"
android:text="Finish" />
</com.example.wizardtest.WizardStepView>
</com.example.wizardtest.WizardView>
</RelativeLayout>
Activity:
WizardView wizardView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
wizardView = (WizardView) findViewById(R.id.wizard);
wizardView.startWizard();
}

New class extends FrameLayout could not be instantiated

I wrote a class extends FrameLayout.
public class ReaderFrameLayout extends FrameLayout
{
public ReaderFrameLayout(Context context)
{
this(context, null);
}
public ReaderFrameLayout(Context context, AttributeSet attrs)
{
this(context, attrs, 0);
}
public ReaderFrameLayout(Context context, AttributeSet attrs, int defaultStyle)
{
super(context, attrs, defaultStyle);
WebView readerWebView = (WebView) findViewById(R.id.fragment_reader_webview);
readerWebView.setOnTouchListener(new OnTouchListener()
{
#Override
public boolean onTouch(View v, MotionEvent event)
{
Log.d("ReaderFrameLayout", "setOnTouchListener");
return true;
}
});
}
}
And add it to a fragment.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<com.mbs.helpers.ReaderFrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginTop="83dp" >
<WebView
android:id="#+id/fragment_reader_webview"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</com.mbs.helpers.ReaderFrameLayout>
</RelativeLayout>
An error in Eclipse:
com.android.layoutlib.bridge.MockView cannot be cast to android.view.ViewGroup
Exception details are logged in Window > Show View > Error Log
The following classes could not be instantiated:
- com.mbs.helpers.ReaderFrameLayout (Open Class, Show Error Log)
See the Error Log (Window > Show View) for more details.
Tip: Use View.isInEditMode() in your custom views to skip code when shown in Eclipse
The application does not work, of course.
What am I doing wrong?
Just create the web view programmatically :
public ReaderFrameLayout(Context context, AttributeSet attrs, int defaultStyle)
{
super(context, attrs, defaultStyle);
WebView readerWebView = new WebView(context);
addView(readerWebView);
readerWebView.setOnTouchListener(new OnTouchListener()
{
#Override
public boolean onTouch(View v, MotionEvent event)
{
Log.d("ReaderFrameLayout", "setOnTouchListener");
return true;
}
});
}
and remove it from the XML layout
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<com.mbs.helpers.ReaderFrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginTop="83dp" />
</RelativeLayout>
If you really want to create your custom view from an XML layout, then you need to do that in a separate XML file and inflate it in your custom class.
For instace, res/layout/reader.xml:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<WebView
android:id="#+id/fragment_reader_webview"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</FrameLayout>
And in your code:
public ReaderFrameLayout(Context context, AttributeSet attrs,
int defaultStyle) {
super(context, attrs, defaultStyle);
LayoutInflater.from(context).inflate(R.layout.reader, this);
WebView readerWebView = (WebView) findViewById(R.id.fragment_reader_webview);
readerWebView.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
Log.d("ReaderFrameLayout", "setOnTouchListener");
return true;
}
});
}

Categories

Resources