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;
}
});
}
Related
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).
ViewHolder is inflated based on this layout:
Adding listener to the whole ViewHolder, or be exact to itemView:
userSettingHolder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
But only the first item the imageView can active the listener. Why not the whole item, with not last two 'sub'-recycleview?
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="66dp">
<ImageView
android:id="#+id/icon"
android:layout_width="66dp"
android:layout_height="66dp"
android:padding="0dp" />
<android.support.v7.widget.RecyclerView
android:id="#+id/rw1"
android:layout_marginStart="66dp"
android:layout_marginTop="0dp"
android:layout_marginBottom="33dp"
android:layout_height="33dp"
android:layout_width="match_parent"/>
<android.support.v7.widget.RecyclerView
android:id="#+id/rw2"
android:layout_marginStart="66dp"
android:layout_marginTop="33dp"
android:layout_marginBottom="0dp"
android:layout_height="33dp"
android:layout_width="match_parent"/>
</RelativeLayout>
Here when you click on ImageView the touch is passed to the parent which will be itemView., But when you click on RecyclerView it consumes the touch.
I suggest you add this property to both RecyclerView in xml
android:clickable="false"
If this didn't work then you have to subclass the RecyclerView and override the onInterceptTouchEvent method.
public class ScrollThroughRecyclerView extends RecyclerView {
public ScrollThroughRecyclerView(Context context) {
super(context);
}
public ScrollThroughRecyclerView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ScrollThroughRecyclerView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
public boolean dispatchTouchEvent(MotionEvent ev) {
return false;
}
#Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return false;
}
}
Then in your xml instead of
<android.support.v7.widget.RecyclerView use <your.file.path.ScrollThroughRecyclerView
But both solutions will make the RecyclerView not clickable, and ofcourse not scrollable.
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.
In fact i know how to open an activity by clicking on a button
But i can't do it in frame layout
i try this code but it didn't help me.
FrameLayout ff=(FrameLayout)findViewById(R.id.btn);
ff.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent=new Intent(listActivity.this,bookActivity.class);
startActivity(intent);
}
});
that's all
EDITES:
this my activity_main :
<LinearLayout
android:id="#+id/linbook"
android:layout_margin="15dp"
android:layout_toRightOf="#+id/linjozve"
android:layout_width="130dp"
android:layout_height="180dp"
android:orientation="vertical">
<FrameLayout
android:id="#+id/ketabbtn"
android:layout_width="130dp"
android:layout_height="130dp">
<ImageButton
android:layout_weight="1"
android:id="#+id/btntopright"
android:layout_width="130dp"
android:layout_height="130dp"
android:background="#drawable/rgreen"/>
<ImageButton
android:background="#drawable/book"
android:layout_gravity="center"
android:layout_width="80dp"
android:layout_height="80dp" />
</FrameLayout>
<TextView
android:layout_marginTop="15dp"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="book"/>
</LinearLayout>
thanks
Try to set android:clickable in the xml.
If that doesn't work try to create a custom layout:
By default, onInterceptTouchEvent returns false. So include following code and use this CustomClickableFrameLayout instead of framelayout
public class CustomClickableFrameLayout extends FrameLayout {
private OnClickListener mOnClickListener;
#Override
public void setOnClickListener(OnClickListener l) {
super.setOnClickListener(l);
mOnClickListener = l;
}
#Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return mOnClickListener != null;
}
// Standard constructors — just pass everything
public CustomClickableFrameLayout (final Context context) {
super(context);
}
public CustomClickableFrameLayout (final Context context, final AttributeSet attrs) {
super(context, attrs);
}
public CustomClickableFrameLayout (final Context context, final AttributeSet attrs, final int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
public CustomClickableFrameLayout (final Context context, final AttributeSet attrs, final int defStyleAttr, final int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
}
The problem is it is quite hard to click on a FrameLayout if it is covered by other views. In your case, the framelayout and the imagebutton have the same size 130x130. This explains why the touch cannot reach the layout.
To make sure you can click it, add some padding between the layout and its childs. (I reduced the size of its child)
<FrameLayout
android:padding="10dp"
android:id="#+id/ketabbtn"
android:layout_width="130dp"
android:layout_height="130dp">
<ImageButton
android:layout_weight="1"
android:id="#+id/btntopright"
android:layout_width="120dp"
android:layout_height="120dp"
android:background="#drawable/rgreen"/>
<ImageButton
android:background="#drawable/book"
android:layout_gravity="center"
android:layout_width="80dp"
android:layout_height="80dp" />
</FrameLayout>
Also, you used wrong ID. So change this:
FrameLayout ff=(FrameLayout)findViewById(R.id.btn);
To this:
FrameLayout ff=(FrameLayout)findViewById(R.id.ketabbtn);
So you can click the padding space to trigger the onClick event.
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>