ListView collapse in CustomScrollView - android

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.

Related

ViewHolder itemView is smaller than expected

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.

How to open An Activity by Clicking On FrameLayout?

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.

Android - HorizontalScrollView scrolls to the right when keyboard is opened

I have a general layout for my app in place, which includes a horizontal scroll view.
What I'm doing is adding 32 fragments to the scroll view (which inflates into a vertical linear layout with two buttons and an editText. They're going to be controls for an equalizer).
The problem is, when I try to edit one of the editText's, the scrollview scrolls all the way to the right - so you're unable to see what you're typing into, and have to scroll all the way back to that entry to view it.
Here's the main xml layout. It splits the screen up into 4 quadrants, with the horizontal scroll view going in the bottom right:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:orientation="horizontal"
tools:context=".MainActivity"
android:focusable="true"
android:focusableInTouchMode="true">
<LinearLayout
android:layout_width="0dp"
android:layout_height="fill_parent"
android:padding="4dp"
android:orientation="vertical"
android:layout_weight="2"
>
<TextView android:text="Hello World!" android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_weight="4"
android:padding="4dp"
android:orientation="vertical"
android:background="#FF0000"
>
<TextView android:text="Hello World!" android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<HorizontalScrollView
android:id="#+id/hsv_eqControls"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="2dp"
android:background="#FFFFFF"
android:descendantFocusability="beforeDescendants"
android:focusable="true"
android:focusableInTouchMode="true"
>
<LinearLayout
android:id="#+id/layout_eqControls"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
</LinearLayout>
</HorizontalScrollView>
</LinearLayout>
</LinearLayout>
And this is what I'm adding into the scrollview
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="3dp"
android:orientation="vertical">
<Button
android:id="#+id/btn_eqUp"
android:layout_width="60dp"
android:layout_height="60dp" />
<EditText
android:id="#+id/etext_eq"
android:layout_width="60dp"
android:layout_height="wrap_content"
android:inputType="numberDecimal|numberSigned"
android:textAlignment="center"
android:layout_gravity="center_horizontal"
android:background="#EEEEEE"
android:hint="32dB"/>
<Button
android:id="#+id/btn_eqDown"
android:layout_width="60dp"
android:layout_height="60dp" />
<TextView
android:id="#+id/vtext_eqLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAlignment="center"
android:layout_gravity="center"
android:text="1"/>
</LinearLayout>
This is the code I'm running to fill the scrollview:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// View eqControls = findViewById(R.id.hsv_eqControls);
FragmentTransaction ft = getFragmentManager().beginTransaction();
for(int i = 1; i < 33; i++)
{
ft.add(R.id.layout_eqControls, new FragmentEQ(), "ch"+i);
}
ft.commit();
getFragmentManager().executePendingTransactions();
for(int i = 1; i < 33; i++)
{
FragmentEQ feq = (FragmentEQ) getFragmentManager().findFragmentByTag("ch"+i);
if(feq != null)
feq.setChannel(i);
}
}
}
And this is the code for my fragment:
public class FragmentEQ extends Fragment {
protected int _channel = 0;
protected ViewGroup _parent;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.activity_fragment_eq, container, false);
TextView label = (TextView) view.findViewById(R.id.vtext_eqLabel);
label.setText(Integer.toString(_channel));
return view;
}
public int getChannel() { return _channel; }
public void setChannel(int i)
{
_channel = i;
}
}
I've tried creating a custom HorizontalScrollView, and overriding scrollTo() and onRequestFocusInDescendants() as blank methods that do nothing, but this changes nothing.
public class EQScrollView extends HorizontalScrollView {
public EQScrollView( Context context, AttributeSet attrs)
{
super(context, attrs);
setSmoothScrollingEnabled(false);
}
#Override
public void scrollTo(int x, int y)
{
}
#Override
public boolean onRequestFocusInDescendants(int x, Rect y)
{
return false;
}
}
Using "setRawInputType":
setRawInputType(InputType.TYPE_CLASS_NUMBER);
solved the issue for me at first. After realizing that some number keyboards don't provide decimal input I ended up using standard text input for EditText, extending HorizontalScrollView and overriding "onRequestFocusInDescendants", "requestChildRectangleOnScreen" and "getFocusables" like so:
public class HorizontalScrollViewEx extends HorizontalScrollView {
public HorizontalScrollViewEx(Context context) {
super(context);
}
public HorizontalScrollViewEx(Context context, AttributeSet attrs) {
super(context, attrs);
}
public HorizontalScrollViewEx(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public HorizontalScrollViewEx(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
#Override
protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) {
return true;
}
#Override
public boolean requestChildRectangleOnScreen(View child, Rect rectangle, boolean immediate) {
return true;
}
#Override
public ArrayList<View> getFocusables(int direction) {
return new ArrayList<View>();
}
}
I have just encountered this problem and for me the scrolling to the end only happens when android:inputType is not set in the EditText. If you remove this then the issue should vanish.
FYI even using .setInputType(InputType.TYPE_CLASS_NUMBER); produces this error.
Admittedly this isn't a fix but it's worth noting the cause.
HorizontalScrollView always scroll to the right when I try to click the EditText
I have fixed the similar by the way below:
In my scenario
<HorizontalScrollView
android:id="#+id/id_HorizontalScrollView"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/border_left_black_bold">
<android.support.v7.widget.RecyclerView
android:id="#+id/id_RecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</HorizontalScrollView>
RecyclerView's item view:
<LinearLayout>
<EditText
android:id="#+id/id_edit"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#drawable/border_right_black"
android:gravity="center"
android:inputType="number" />
<LinearLayout/>
Solution in my way:
Customize HorizontalScrollView and override the requestChildRectangleOnScreen method
#Override
public boolean requestChildRectangleOnScreen(View child, Rect rectangle, boolean immediate) {
return true;
}
#Override
protected int computeScrollDeltaToGetChildRectOnScreen(Rect rect) {
return 0;
}
root causes
Let's back to the Android source code.
when the soft keyboard pop up. the size of layout changed View.java protected void onLayout(boolean changed, int left, int top, int right, int bottom)
/**
* Called from layout when this view should
* assign a size and position to each of its children.
* ....
*/
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
}
Then HorizontalScrollView.java protected void onLayout(boolean changed, int left, int top, int right, int bottom)
In this method, mIsLayoutDirty = false;
HorizontalScrollView.java public void requestChildFocus(View child, View focused)
HorizontalScrollView.java private void scrollToChild(View child)
HorizontalScrollView.java
int scrollDelta = computeScrollDeltaToGetChildRectOnScreen(mTempRect);
if(scrollDelta!=0){
scrollBy(scrollDelta, 0);
}

Parent click event not firing when recyclerview clicked

I have a RecyclerView which is in a CardView that has a couple of TextViews. The CardView has a OnClickListener set and is fired off when clicking on the TextViews, but does not fire when clicking on the RecyclerView.
Here is what the CardView looks like:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="#+id/card_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp"
card_view:cardCornerRadius="4dp"
card_view:cardElevation="5dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:weightSum="100"
android:minWidth="100dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:id="#+id/text1"
android:textColor="#color/abc_primary_text_material_light"
android:layout_weight="1"
android:layout_gravity="center_horizontal" />
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:listSelector="#color/highlighted_text_material_light"
android:layout_weight="98" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#android:color/black" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/relativeSummary"
android:orientation="horizontal"
android:layout_weight="1">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:id="#+id/text2"
android:textAlignment="viewEnd"
android:textColor="#color/abc_secondary_text_material_light"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:gravity="start"
android:singleLine="true"
android:layout_alignParentLeft="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:id="#+id/text3"
android:textColor="#color/abc_primary_text_material_light"
android:layout_marginRight="5dp"
android:layout_marginLeft="5dp"
android:gravity="end"
android:singleLine="true"
android:layout_alignParentRight="true"
android:layout_toRightOf="#+id/text2" />
</RelativeLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
I do not need a click listener on this RecyclerView and really only need the parent view's click event to fire when the RecyclerView is clicked (The same goes for the OnLongClick event). I also need the RecyclerView to scroll. Is the RecyclerView some how eating the click event and not passing it up to the parent?
There is a better solution. That is, subclass your CardView:
public class InterceptTouchCardView extends CardView {
public InterceptTouchCardView(Context context) {
super(context);
}
public InterceptTouchCardView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public InterceptTouchCardView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
/**
* Intercept touch event so that inner views cannot receive it.
*
* If a ViewGroup contains a RecyclerView and has an OnTouchListener or something like that,
* touch events will be directly delivered to inner RecyclerView and handled by it. As a result,
* parent ViewGroup won't receive the touch event any longer.
*/
#Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return true;
}
}
recyclerView.setLayoutFrozen(true);
just setLayoutFrozen true after setAdapter for recyclerView
In my case, I had a CardView with a couple of buttons and a RecyclerView. With the solutions of ywwynm and Daryl the problem was that the CardView would intercept the events from all of its children views, including the buttons. But what I wanted was for the CardView to intercept the touch events of the RecyclerView only. My solution was the following:
public class UntouchableRecyclerView extends RecyclerView {
public UntouchableRecyclerView(Context context) {
super(context);
}
public UntouchableRecyclerView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public UntouchableRecyclerView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#Override
public boolean onTouchEvent(MotionEvent e) {
return false;
}
}
I figured out how to get the click event to the RecyclerView's parent. My solution kind of feels like a hack, so I'm hoping that someone can come up with a better solution.
In the RecylerView.Adapter:
#Override
public ViewHolder onCreateViewHolder(final ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.my_item_layout, viewGroup, false);
ViewHolder viewHolder = new ViewHolder(view);
viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
viewGroup.callOnClick();
}
});
viewHolder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
return viewGroup.performLongClick();
}
});
return viewHolder;
}
I then had to hook up the click event on the RecyclerView:
RecyclerView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
parentView.callOnClick();
}
});
RecyclerView.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
return parentView.performLongClick();
}
});
#ywwynm, you are on the right track except the solution doesn't allow the nested RecyclerView to scroll. I combined it with the solution here and came up with this solution to handle click and onLongClick events as well as to allow scrolling.
public class InterceptTouchCardView extends CardView {
private GestureDetector mGestureDetector;
private boolean mLongClicked;
public InterceptTouchCardView(Context context) {
super(context);
Initialize();
}
public InterceptTouchCardView(Context context, AttributeSet attrs) {
super(context, attrs);
Initialize();
}
public InterceptTouchCardView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
Initialize();
}
private void Initialize() {
mGestureDetector = new GestureDetector(getContext(),
new GestureDetector.SimpleOnGestureListener() {
public boolean onDown(MotionEvent e) {
mLongClicked = false;
return true;
}
public void onLongPress(MotionEvent e) {
mLongClicked = true;
performLongClick();
}
});
}
/**
* Intercept touch event so that inner views cannot receive it.
*
* If a ViewGroup contains a RecyclerView and has an OnTouchListener or something like that,
* touch events will be directly delivered to inner RecyclerView and handled by it. As a result,
* parent ViewGroup won't receive the touch event any longer.
*
* We can't Intercept the touch event if we want to allow scrolling since ACTION_DOWN always
* happens before ACTION_MOVE. So handle touch events here since onTouchEvent won't be triggered.
*/
#Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
mGestureDetector.onTouchEvent(ev);
if (ev.getAction() == MotionEvent.ACTION_UP && !mLongClicked)
this.callOnClick();
return false;
}
}

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