Reputation: 403
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;
}
}
Upvotes: 3
Views: 802
Reputation: 944
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/>
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;
}
Let's back to the Android source code.
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) {
}
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);
}
Upvotes: 0
Reputation: 3001
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>();
}
}
Upvotes: 2
Reputation: 5241
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.
Upvotes: 1