How to set images for ScrollView instead-of fading edges? - android

I am using Horizontal Scroll View, dynamically i will add items in to that. if no. of items are more than displaying items on the screen i want to show image(arrow) at the edges ( like scroll view shows fading edges). How can i do it.
just look at below image, i want create like that.
this is the xml code
<HorizontalScrollView
android:layout_width="wrap_content"
android:scrollbars="none"
android:id="#+id/app_category"
android:layout_below="#+id/top_layout"
android:background="#drawable/minitopbar"
android:layout_height="30dp">
<LinearLayout
android:orientation="horizontal"
android:id="#+id/app_category_scroll_layout"
android:layout_width="wrap_content"
android:layout_height="fill_parent"/>
</HorizontalScrollView>

A. You have to create your own class, that extends HorizontalScrollView:
public class ExtendedHorizontalScrollView extends HorizontalScrollView {
private IScrollStateListener scrollStateListener;
public HorizontalScrollViewForMenu(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public HorizontalScrollViewForMenu(Context context, AttributeSet attrs) {
super(context, attrs);
}
public HorizontalScrollViewForMenu(Context context) {
super(context);
}
#Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
prepare();
}
private void prepare() {
if (scrollStateListener != null) {
View content = this.getChildAt(0);
if (content.getLeft() >= 0)
scrollStateListener.onScrollMostLeft();
if (content.getLeft() < 0)
scrollStateListener.onScrollFromMostLeft();
if (content.getRight() <= getWidth())
scrollStateListener.onScrollMostRight();
if (content.getLeft() > getWidth())
scrollStateListener.onScrollFromMostRight();
}
}
#Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
if (scrollStateListener != null) {
if (l == 0)
scrollStateListener.onScrollMostLeft();
else if (oldl == 0)
scrollStateListener.onScrollFromMostLeft();
int mostRightL = this.getChildAt(0).getWidth() - getWidth();
if (l >= mostRightL)
scrollStateListener.onScrollMostRight();
if (oldl >= mostRightL && l < mostRightL)
scrollStateListener.onScrollFromMostRight();
}
}
public void setScrollStateListener(IScrollStateListener listener) {
scrollStateListener = listener;
}
public interface IScrollStateListener {
void onScrollMostLeft();
void onScrollFromMostLeft();
void onScrollMostRight();
void onScrollFromMostRight();
}
}
B. Use it defining of layout:
<LinearLayout
.....>
<ImageView
android:id="#+id/navigation_left"
..... />
<your.custom.view.package.ExtendedHorizontalScrollView
android:id="#+id/scroller"
android:layout_width="0px"
android:layout_weight="1"
android:fadingEdge="none"
....>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</your.custom.view.package.ExtendedHorizontalScrollView>
<ImageView
android:id="#+id/navigation_right"
..... />
</LinearLayout>
C. Add logic for disabling arrows when you can't scroll any more.
((ExtendedHorizontalScrollView)findViewById(R.id.scroller)).setScrollStateListener(new IScrollStateListener() {
public void onScrollMostRight() {
((View) scroller.getParent()).findViewById(R.id.navigation_right).setVisibility(View.INVISIBLE);
}
public void onScrollMostLeft() {
((View) scroller.getParent()).findViewById(R.id.navigation_left).setVisibility(View.INVISIBLE);
}
public void onScrollFromMostLeft() {
((View) scroller.getParent()).findViewById(R.id.navigation_left).setVisibility(View.VISIBLE);
}
public void onScrollFromMostRight() {
((View) scroller.getParent()).findViewById(R.id.navigation_right).setVisibility(View.VISIBLE);
}
});

An easy alternative is to make a scrollview without fading edges and then add the image with arrow below or on top of the scrollview.
Your xml something similar:
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ListView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentTop="true"
android:fadingEdge="none"
/>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<View
android:layout_height="6dp"
android:layout_width="fill_parent"
android:layout_alignParentBottom="true"
android:background="#drawable/background_effect"/>
</RelativeLayout>
</FrameLayout>

Related

notifyDataSetChanged() refresh the whole layout

I didn't describe the question in a good way, so I edit the question to be clear.
I am so confused about this: I wrote a RelativeLayout with a DragViewGroup and a gridview, and I noticed that every time when I used notifyDatasetChanged() method would cause the DragViewGroup do the redrawing thing.And the DragViewGroup extends from LinearLayout which uses ViewDragHelper, so I could not maintain the position already scrolled to.
Here is my xml file:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.xxxx.DragViewGroup
android:id="#+id/dragview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#3f83f7"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="665dp"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="310dp"
android:id="#+id/mainview"
>
...
</RelativeLayout>
<include
android:layout_width="match_parent"
android:layout_height="355dp"
android:layout_marginBottom="62dp"
layout="#layout/fake_panel" />
</LinearLayout>
</com.xxxx.DragViewGroup>
<RelativeLayout
android:layout_width="match_parent"
android:id="#+id/layout"
android:layout_alignParentBottom="true"
android:layout_height="210dp"
android:background="#ffffff"
android:clickable="true"
>
<HorizontalScrollView
android:id="#+id/btn_scroll_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:overScrollMode="never"
android:layout_alignParentBottom="true"
android:layout_marginBottom="26dp"
android:scrollbars="none">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<GridView
android:id="#+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:listSelector="#color/transparent"
android:horizontalSpacing="6dp"
android:scrollbars="none" />
</LinearLayout>
</HorizontalScrollView>
<com.xxxx.UniversalSeekBar
....
android:layout_marginTop="18dp"/>
</RelativeLayout>
</RelativeLayout>
DragViewGroup code:
public class DragViewGroup extends LinearLayout {
private ViewDragHelper viewDragHelper;
private View mainView;
private int mainHeight;
public DragViewGroup(Context context) {
super(context);
initView();
}
public DragViewGroup(Context context, AttributeSet attrs) {
super(context, attrs);
initView();
}
public DragViewGroup(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView();
}
#Override
protected void onFinishInflate() {
super.onFinishInflate();
mainView = getChildAt(0);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mainHeight = mainView.findViewById(R.id.mainview).getMeasuredHeight();
}
#Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return viewDragHelper.shouldInterceptTouchEvent(ev);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
viewDragHelper.processTouchEvent(event);
return true;
}
#Override
public void computeScroll() {
if (viewDragHelper.continueSettling(true)) {
ViewCompat.postInvalidateOnAnimation(this);
}
}
private void initView() {
viewDragHelper = ViewDragHelper.create(this, callback);
}
private ViewDragHelper.Callback callback = new ViewDragHelper.Callback() {
#Override
public boolean tryCaptureView(View child, int pointerId) {
return mainView == child;
}
#Override
public int clampViewPositionHorizontal(View child, int left, int dx) {
return 0;
}
#Override
public int clampViewPositionVertical(View child, int top, int dy) {
return top;
}
#Override
public void onViewReleased(View releasedChild, float xvel, float yvel) {
super.onViewReleased(releasedChild, xvel, yvel);
if (mainView.getTop() > -500) {
viewDragHelper.smoothSlideViewTo(mainView, 0, 0);
ViewCompat.postInvalidateOnAnimation(DragViewGroup.this);
} else {
viewDragHelper.smoothSlideViewTo(mainView, 0, -mainHeight);
ViewCompat.postInvalidateOnAnimation(DragViewGroup.this);
}
}
};
}
Once I use the notifyDatasetChanged() method to update the gridview, my DragViewGroup will slide to the original position itself although it has been dragged before. Apparently the method draw the whole layout instead of only drawing gridview itself.
I need to maintain the dragged position of DragViewGroup, I have tried that override onDraw method in DragViewGroup like this:
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// set isDragged label in onViewReleased()
if (isDragged) {
viewDragHelper.smoothSlideViewTo(main, 0, -mainHeight);
}
}
It works, but there is a visible sliding process which I don't want.
Hope someone could help me.Thanks very much.
Store ScrollValue at the time of the scrolling the view, and just use setSelectionMethod on your gridview
gridview.setOnScrollListener(new OnScrollListener() {
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
// TODO Auto-generated method stub
int count = gridview.getCount();
if (scrollState == SCROLL_STATE_IDLE) {
if (gridview.getLastVisiblePosition() >= count
- 1) {
scrollPos = <positionOfList>;
}
}
}
});
Here enter your last position insted of "positionOfList"
And just after calling notifydatasetChanged() call gridview.setSelection(scrollPos)
Hope this will help you!
Just use bellow code in class that you update display:
int index = myList.getFirstVisiblePosition();
View v = myList.getChildAt(0);
int top = (v == null) ? 0 : v.getTop();
myList.setAdapter(adapter);
adapter.notifyDataSetChanged();
myList.setSelectionFromTop(index, top);

Hide linearlayout on webview scroll

I have an app screen, where I have a webview, and a linear layout of buttons at the bottom of the screen. I have a scroll listener attached to the webview, which is giving me values when scrolled. What I really want to do, is gradually hide the bottom linear layout when scrolling down, and show when scrolling up, as seen in a fair few apps, but all the examples I can see are toolbars at the top of the screen.
I have tried a number of things, I have tried getting the height of the linear layout, and then on scrolling, move it in the y axis to hide and show, and this moved the buttons within but not the actual bar.
The main thing I tried, is when scrolling, decreasing the height of the bar and when it reaches 0 hiding it, and then showing it again, but this is squashing the buttons rather than scrolling them off the bottom of the screen without changing their size.
This is the layout:
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:id="#+id/buttonBar"
android:background="#403152"
android:visibility="gone"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp">
<ImageButton
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:id="#+id/facebookLink"
android:src="#string/button1"
android:layout_weight="1"
android:onClick="openLink"
android:background="#android:color/transparent"/>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:id="#+id/linkedinLink"
android:src="#string/button2"
android:layout_weight="1"
android:background="?android:selectableItemBackground"
android:onClick="openLink"/>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:id="#+id/twitterLink"
android:src="#string/button3"
android:layout_weight="1"
android:background="?android:selectableItemBackground"
android:onClick="openLink"/>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:id="#+id/instagramLink"
android:src="#string/button4"
android:layout_weight="1"
android:background="?android:selectableItemBackground"
android:onClick="openLink"/>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="#mipmap/ic_overflow"
android:layout_weight="1"
android:layout_gravity="center"
android:background="?android:selectableItemBackground"
android:onClick="showPopup"
android:id="#+id/aboutoption"/>
</LinearLayout>
<holidays.ObservableWebView
android:id="#+id/scrollableWebview"
android:layout_width="fill_parent"
android:clickable="false"
android:layout_height="fill_parent"
android:layout_alignParentTop="true"
android:layout_above="#id/buttonBar"
android:visibility="gone"/>
and then this is the code I have tried so far, which includes changing the height, etc - Hoping someone may be able to point me in the right direction of what I am doing wrong, or what may be a better way to tackle this.
mWebView.setOnScrollChangedCallback(new ObservableWebView.OnScrollChangedCallback(){
public void onScroll(int l, int t){
int height = mWebView.getMeasuredHeight();
Log.d("HEIGHT", Integer.toString(height));
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int screenHeight = size.y;
Log.d("Screen HEIGHT", Integer.toString(screenHeight));
LinearLayout layout = (LinearLayout)findViewById(R.id.buttonBar);
View contentsView = findViewById(R.id.buttonBar);
if(firstScroll == true){
mWebView.setLayoutParams(new RelativeLayout.LayoutParams(mWebView.getMeasuredWidth(), mWebView.getMeasuredHeight() + 10));
/*originalButtonBarHeight = findViewById(R.id.buttonBar).getHeight();
currentButtonBarHeight = originalButtonBarHeight;
contentsView.getLocationOnScreen(screenBarPosition);
contentsView.setY(screenBarPosition[1] + 1);
firstScroll = false;
layout.getLayoutParams().height = t + 1;
layout.requestLayout();
directionVal = t;*/
}
else if(firstScroll == false){
if(directionVal < t){
mWebView.setLayoutParams(new RelativeLayout.LayoutParams(mWebView.getMeasuredWidth(), mWebView.getMeasuredHeight() + 10));
/* Log.d("DOWN", Integer.toString(t));
if(currentButtonBarHeight <= 0){
//do nothing
}
else{
currentButtonBarHeight = currentButtonBarHeight - 5;
if(currentButtonBarHeight <= 0){
currentButtonBarHeight = 0;
layout.getLayoutParams().height = 0;
layout.requestLayout();
findViewById(R.id.buttonBar).setVisibility(View.GONE);
}
else{
contentsView.getLocationOnScreen(screenBarPosition);
contentsView.setY(screenBarPosition[1] + 1);
layout.getLayoutParams().height = currentButtonBarHeight;
layout.requestLayout();
}
}
/*if(t + 5 < originalButtonBarHeight) {
}*/
}
else if(directionVal > t){
Log.d("UP", Integer.toString(currentButtonBarHeight));
/*decreasedAmount = t - 5;
if (decreasedAmount < originalButtonBarHeight){
layout.getLayoutParams().height = t - 5;
layout.requestLayout();
}*/
}
directionVal = t;
}
}
});
You can do this one by CustomWebView:
CustomWebView.java:
public class CustomWebView extends WebView {
private GestureDetector gestureDetector;
public CustomWebView(Context context) {
super(context);
}
public CustomWebView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomWebView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
}
#Override
public boolean onTouchEvent(MotionEvent ev) {
return gestureDetector.onTouchEvent(ev) || super.onTouchEvent(ev);
}
public void setGestureDetector(GestureDetector gestureDetector) {
this.gestureDetector = gestureDetector;
}
}
web_fragment.xml:
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/transparent"
android:orientation="vertical">
<com.customview.CustomWebView
android:id="#+id/customWebView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusable="true" />
// Your other Linear layout
</LinearLayout>
CustomeGestureDetector clss for Gesture Detection (I have added in Fragment):
private class CustomeGestureDetector extends GestureDetector.SimpleOnGestureListener {
#Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
if(e1 == null || e2 == null) return false;
if(e1.getPointerCount() > 1 || e2.getPointerCount() > 1) return false;
else {
try {
if(e1.getY() - e2.getY() > 20 ) {
// Show Your Linear Layout
customWebView.invalidate();
return false;
}
else if (e2.getY() - e1.getY() > 20 ) {
// Hide Your Linear Layout
customWebView.invalidate();
return false;
}
} catch (Exception e) {
customWebView.invalidate();
}
return false;
}
}
}
WebFragment.java:
private CustomWebView customWebView;
customWebView= (CustomWebView) view.findViewById(R.id.customWebView);
customWebView.setGestureDetector(new GestureDetector(new CustomeGestureDetector()));
Hope it would help you.
Make your root view as CoordinatorLayout.
Wrap your content into NestedScrollView.
Add following to your bottom View:
app:layout_behavior="com.google.android.material.behavior.HideBottomViewOnScrollBehavior">

How to make a vertical TextView

I am making an application in Android and I am currently trying to make a vertical TextView. I want it to look similar to this.
Does anyone know how to achieve this, or at least an existing library which I can use to get this effect.
Thanks
If you want vertical Text View like this then you need to pass \n to Text View text property.
Refer this.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/description"
android:layout_width="wrap_content"
android:layout_height="100dp"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:layout_marginLeft="10dp"
android:layout_marginRight="5dp"
android:layout_marginTop="5dp"
android:background="#000"
android:paddingLeft="20dp"
android:paddingRight="20dp"
android:paddingTop="5dp"
android:text="A\nB\nC\nD\n"
android:textColor="#FFF"
android:textSize="18dp" />
</RelativeLayout>
You must create custom view
For example:
public class VerticalTextView extends AppCompatTextView {
final boolean topDown;
public VerticalTextView(Context context, AttributeSet attrs) {
super(context, attrs);
final int gravity = getGravity();
if (Gravity.isVertical(gravity) && (gravity & Gravity.VERTICAL_GRAVITY_MASK) == Gravity.BOTTOM) {
setGravity((gravity & Gravity.HORIZONTAL_GRAVITY_MASK) | Gravity.TOP);
topDown = false;
} else
topDown = true;
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(heightMeasureSpec, widthMeasureSpec);
setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth());
}
#Override
protected boolean setFrame(int l, int t, int r, int b) {
return super.setFrame(l, t, l + (b - t), t + (r - l));
}
#Override
public void draw(Canvas canvas) {
if (topDown) {
canvas.translate(getHeight(), 0);
canvas.rotate(90);
} else {
canvas.translate(0, getWidth());
canvas.rotate(-90);
}
canvas.clipRect(0, 0, getWidth(), getHeight(), Region.Op.REPLACE);
super.draw(canvas);
}
}

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);
}

ScrollViewExt - onScrollChanged don't work

I've a little problem on my ScrollViewExt. When I scroll in my view no log is displayed. I read similar problems but I wonder if the use of fragment doesn't change the code a bit ?
In my Log I've just :
ScrollViewExt﹕ setOnScrollViewListener
Thx all for your answers.
ScrollViewExt :
public class ScrollViewExt extends ScrollView {
private OnScrollViewListener scrlViewListener;
public ScrollViewExt(Context context) {
super(context);
}
public ScrollViewExt(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ScrollViewExt(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public void setOnScrollViewListener(OnScrollViewListener l) {
Log.d("ScrollViewExt", "setOnScrollViewListener ");
this.scrlViewListener = l;
}
#Override
protected void onScrollChanged(int x, int y, int oldx, int oldy) {
Log.d("ScrollViewExt", "onScrollChanged");
super.onScrollChanged(x, y, oldx, oldy);
if(scrlViewListener != null) {
scrlViewListener.onScrollChanged(this, x, y, oldx, oldy);
}
}
}
FragmentNew.java :
public class FragmentNew extends Fragment implements OnScrollViewListener {
ScrollViewExt scrlvNew;
public FragmentNew() {
}
#Override
public View onCreateView(LayoutInflater inflater, final ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_new, container,
false);
scrlvNew = (ScrollViewExt) view.findViewById(R.id.scrlvFragmentNew);
scrlvNew.setOnScrollViewListener(this);
return view;
}
#Override
public void onScrollChanged(ScrollViewExt v, int x, int y, int oldl, int oldt) {
Log.d("FragmentNew", "onScrollChanged");
Log.d("Fragment", "x : " + x);
Log.d("Fragment", "y : " + y);
Log.d("Fragment", "oldx : " + oldl);
Log.d("Fragment", "oldy : " + oldt);
}
}
My Layout :
<?xml version="1.0" encoding="utf-8"?>
<com.application.view.ScrollViewExt
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/scrlvFragmentNew"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/white"
android:orientation="vertical"
android:overScrollMode="always"
android:isScrollContainer="true"
android:scrollbarAlwaysDrawVerticalTrack="true"
android:scrollbarStyle="outsideInset"
android:scrollbars="vertical"
>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<TextView
android:id="#+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20dp"
android:textColor="#android:color/black"/>
<TextView
android:id="#+id/description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="15dp"
android:textColor="#android:color/black"
android:layout_below="#+id/title"/>
</RelativeLayout>
</com.application.view.ScrollViewExt>
I managed to get a result but I completely change the layout for a SwipeRefreshLayout .
What I hope to achieve is in this idea, but the only thing he really misses me and if that is not possible it is shameful :-) , change the arrow that turns, and I want to put a cross . I managed to hide the arrow but not with a cross .
http://i.stack.imgur.com/nPgrQ.png
or here :
http://openclassrooms.com/forum/sujet/android-scrollview-detecter-le-top?page=1#message-88666797

Categories

Resources