TextView with scrollbar that can handle onTouchEvents - java

I have problem with handling Touch events inside my TextView on Android 2.3.3. I've got Activity implements OnTouchListener with method
main.java
public boolean onTouchEvent(MotionEvent event) {
if(event.getPointerCount()==1){
textView.setTextSize(mRatio+13);
mRatio++;
Log.d("TouchEvent", "one touch !");
}
if (event.getPointerCount() == 2) {
some code...
}
return true;
}
and my layout(only part of it):
<LinearLayout android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_weight="1.0"
android:fadingEdge="none"
android:background="#color/white">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_margin="10dp">
<!-- TEXT EMAIL : -->
<TextView
android:id="#+id/mail_text"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:textSize="15sp"
android:autoLink="web"
android:clickable="true"
android:textColor="#color/mailtext"
android:scrollbars = "vertical"/>
</LinearLayout>
</LinearLayout>
When i 'clicked' anywhere outside my textBox(for example on header or footer), the Touch event trigger, font get bigger. I assume than the problem is probably because scrollbars. But when I cut off android:scrollbars = "vertical" bar just disappear.
This textView usually contain a lots of text.
How to proper fire onTouchEvents inside this textView.
Edit:
when this textView is small my touchEvent work until i get text so big, than the scrollBar is needed. Then all touch event get overrided and You can only scroll textView. No TouchEvent is called.

I handle the problem in other way. OnTouchEvent didn't worked with my TextView so I Override dispatchTouchEvent. It's far more better to performe actions "onTouch".Scrollbar is working and I can add my multitouch events on the whole screen. It's look like:
#Override
public boolean dispatchTouchEvent(MotionEvent motionEvent){
Log.v("NotificationActivity.dispatchTouchEvent()", "got touch");
if (motionEvent.getPointerCount() == 2) {
Log.v("touch", "multi touch !");
int action = motionEvent.getAction();
int pureaction = action & MotionEvent.ACTION_MASK;
// some actions ...
}
switch (motionEvent.getAction()){
case MotionEvent.ACTION_DOWN:{
//Keep track of the starting down-event.
Log.v("akcjaa","down");
// some actions ...
break;
}
case MotionEvent.ACTION_UP:{
//Consume if necessary and perform the fling / swipe action
//if it has been determined to be a fling / swipe
Log.v("akcjaa","up");
break;
}
}
return super.dispatchTouchEvent(motionEvent);
}

I am assuming your TextView is inside some kind of ScrollView or Scrollable container, right?
Then you will face this issue. Android does not like his apples and pears mixed, you should not be trying to receive "onTouch" events that are being consumed by the father layout on top of the view.
I guess you could:
a) Switch to a onClickListener on your TextView
b) Override your parent view layout touch handler to bleed the touch down to its childs. This is not really 100% recommended, and could cause unwanted behaviour.
Sorry if i cannot be of more help.

Related

Edit Text - Focus on Touch

I have created a note app.
In my app when i create a new note. By default, the cursor is at title edit text but I want to have a feature that if I touch anywhere on the screen the cursor should go to the description edit text. I have kept the description edit text in a separate linear layout which has a weight of 1.
Kindly find the images to get an idea.
In the given picture the area covered with the blue line I want to touch anywhere in that area and my focus should be directed to edit text where I have written the hint description
XML
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="#+id/scview"
android:layout_weight="1">
<EditText
android:id="#+id/body_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#000"
android:textSize="18sp"
android:inputType="textMultiLine"
android:hint="Description"
android:backgroundTint="#android:color/transparent"/>.
</LinearLayout>
Use onClickListener() on parent layout of your xml like this
RelativeLayout parentRelativelayout=(RelativeLayout)findViewByRid(R.id.your_parent_layout_in_xml);
EditText edtDescription=(Edittext)findViewByRid(R.id.body_content);
parentRelativelayoutsetOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
edtDescription.requestFocus();
}
});
You need to override dispatchTouchEvent method and changes focus , as user touch screen , dispatchTouchEvent method will be fired.
#override Boolean dispatchTouchEvent(MotionEvent ev ) {
Toast.makeText(context ,"dispatchTouchEvent", Toast.LENGTH_SHORT).show()
return super.dispatchTouchEvent(ev)
}

When EditText with pre-filled text becomes editable, all text moves to one single line

I have an EditText inside of a ScrollView which is pre-filled with a dynamic amount of text. It could be one line or 50 or more. At this point, the EditText is uneditable and the text is shown just fine. However, when I press a button to make the edit text editable, the entire contents of the EditText are thrown into one very long, horizontally scrolling line.
You can see exactly what I'm talking about here:
https://zippy.gfycat.com/GenerousBigHerring.webm
How can I prevent this from happening? I've been screwing around with this for a while now. I've tried setting lines and maxLines, etc, but I can't figure it out.
Edit:
This is my current ScrollView/EditText:
<ScrollView
android:id="#+id/result_text_scroll_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/result_title_text"
android:layout_above="#+id/result_bottom_sheet"
android:layout_marginTop="20dp"
android:padding="5dp">
<EditText
android:id="#+id/extracted_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:padding="15dp"
tools:text="Hello, World"
android:textColor="#color/black"
android:textStyle="bold"
android:textSize="#dimen/extracted_text_size"
android:textIsSelectable="true"
android:inputType="none"
/>
</ScrollView>
From code, here's what I'm doing to to enable/disable editing:
#Override
public void enableTextEditing() {
mExtractedText.setInputType(InputType.TYPE_TEXT_FLAG_MULTI_LINE);
mExtractedText.setOnKeyListener(this);
}
#Override
public void disableTextEditing() {
mExtractedText.setInputType(InputType.TYPE_NULL);
mExtractedText.setOnKeyListener(null);
}
#Override
public boolean onKey(View view, int i, KeyEvent keyEvent) {
if (keyEvent.getAction() == KeyEvent.ACTION_DOWN && keyEvent.getKeyCode() == KeyEvent.KEYCODE_ENTER) {
//All this does is call the View methods to disable text editing
//and close the keyboard.
mPresenter.doneEditingButtonPressed();
return true;
}
return false;
}
Add android:lines , android:minLines and android:maxLines to your EditText view
Also change android: inputType = "textMultiline"
You can add android:scrollbars="vertical" to your EditText as well if you wish

Grouping EditText

I was wondering if there is a way to group EditText in a way that you can only traverse among a group of them.
The problem is that I rely on reaching the end of the first group and use EditorInfo.IME_ACTION_DONE in order to trigger a certain action.
The inner group of EditTexts is inside a LinearLayout.
Put the text boxes in a layout(linear or relative) only those EditText which you want to make a group. layout will act as group. Add this on your every Edittext xml--
android:maxLines="1"
if it does not works the you can handle focus.
Focus Handling
Focus movement is based on an algorithm which finds the nearest neighbor in a given direction. In rare cases, the default algorithm may not match the intended behavior of the developer.
Change default behaviour of directional navigation by using following XML attributes:
android:nextFocusDown="#+id/.."
android:nextFocusLeft="#+id/.."
android:nextFocusRight="#+id/.."
android:nextFocusUp="#+id/.."
Besides directional navigation you can use tab navigation. For this you need to use
android:nextFocusForward="#+id/.."
To get a particular view to take focus, call
view.requestFocus()
To listen to certain changing focus events use a View.OnFocusChangeListener
Keyboard button
You can use android:imeOptions for handling that extra button on your keyboard.
Additional features you can enable in an IME associated with an editor to improve the integration with your application. The constants here correspond to those defined by imeOptions.
The constants of imeOptions includes a variety of actions and flags, see the link above for their values.
Value example
ActionNext :
the action key performs a "next" operation, taking the user to the next field that will accept text.
ActionDone :
the action key performs a "done" operation, typically meaning there is nothing more to input and the IME will be closed.
Code example:
<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"
tools:context=".MainActivity" >
<EditText
android:id="#+id/editText1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="32dp"
android:layout_marginTop="16dp"
android:imeOptions="actionNext"
android:singleLine="true"
android:ems="10" >
<requestFocus />
</EditText>
<EditText
android:id="#+id/editText2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/editText1"
android:layout_below="#+id/editText1"
android:layout_marginTop="24dp"
android:imeOptions="actionDone"
android:singleLine="true"
android:ems="10" />
</RelativeLayout>
If you want to listen to imeoptions events use a TextView.OnEditorActionListener.
editText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
performSearch();
return true;
}
return false;
}
});
Edit:
For dynamic edittext you can try..
EditText etCurrent;
Set an OnTouchlistener on each EditText:
valueET.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (etCurrent != null) {
if (etCurrent.getId() != v.getId()) {
if (!check(etCurrent.getId())) {
etCurrent.setSelection(0,
etCurrent.getText().toString().length());
return true;
} else {
etCurrent = (EditText) v;
}
}
} else {
etCurrent = (EditText) v;
}
}
return false;
}
});

Drag and Drop icons to Home Screen

Update:
to understand my question, here is what i need to achieve:
Drag icon from App drawer to home screen (if possible not in a gridview) like in the pic,
Old (this just to learn how this works):
I'm trying to implement dragging clickable icons from a ListView to a customView with no container(Listview or Gridview...) inside the same Activity or another, here is a picture for you to understand more:
but when i put the icon in the right area i don't see the object, in the log i see: I/ViewRootImpl﹕ Reporting drop result: true
here my code:
class MyDragListener implements View.OnDragListener {
#Override
public boolean onDrag(View v, DragEvent event) {
int action = event.getAction();
switch (event.getAction()) {
...
case DragEvent.ACTION_DROP:
LinearLayoutAbsListView itemo = (LinearLayoutAbsListView)findViewById(R.id.paneko);
View child = getLayoutInflater().inflate(R.layout.list_item, null);
itemo.addView(child);
break;
case DragEvent.ACTION_DRAG_ENDED:
default:
break;
}
return true;
}
}
My XML file:
...
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2"
android:background="#android:color/background_dark"
android:orientation="horizontal" >
<com.moapps.elfassimounir.simple.LinearLayoutAbsListView
android:id="#+id/paneuj"
android:background="#android:color/background_light"
android:orientation="vertical"
>
<ListView
android:id="#+id/listview1"
android:layout_width="100dp"
android:layout_height="wrap_content" />
</com.moapps.elfassimounir.simple.LinearLayoutAbsListView>
<com.moapps.elfassimounir.simple.LinearLayoutAbsListView
android:id="#+id/paneko"
android:background="#android:color/background_light"
android:orientation="vertical" >
</com.moapps.elfassimounir.simple.LinearLayoutAbsListView>
</LinearLayout>
...
Any infos or references (tutorials, docs...) would be very helpful
Have a look at adding a view to the WindowManager(WM). When you long press on an item to be dragged, create your own bitmap of that item and add it to the WM, so that it can be moved without view boundary constraints. When you receive a ACTION_UP or an equivalent event, map your current x,y to the actual view that is directly below the dragged item (Rect classs might be helpful). You can then add this item to that particular view.

autoscrolling textview in android

I'm building a chat-like application that displays text the user inputs to the screen using a scrollview. What I'd like to do is making the scrollview autoscroll as more text is appended to the screen.
I'm using a textview to display the input. The xml portion of the scrollview is as follows:
<ScrollView
android:id="#+id/scroller"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_above="#id/buttons"
>
<LinearLayout
android:id="#+id/start_chat"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
>
</LinearLayout>
</ScrollView>
How do I go about doing that? I tried setting the layout's gravity to "bottom", but that doesn't work correctly (text inputed that moves up as the scrollview is scrolled down can't be viewed again).
Any help is greatly appreciated.
If you want to scroll to the absolute bottom (where new TextView is added) use fullScroll on the ScrollView when the TextView is added.
ScrollView my_scrollview = (ScrollView) findViewById(R.id.scroller);
my_scrollview.fullScroll(ScrollView.FOCUS_DOWN);
If instead you want to scroll relative from the current position the user is viewing, I would try something like smoothScrollBy or scrollBy
/* recently_added_textview being the TextView that was added to trigger this */
ScrollView my_scrollview = (ScrollView) findViewById(R.id.scroller);
int height = recently_added_textview.getHeight();
my_scrollview.smoothScrollBy(0, height);
/* x being 0 assuming you don't want to scroll left and right */
This way the user isn't sent to the bottom of the ScrollView if they're reading something around the top or middle.
You can add this after you added a new chat in your textview
scroller.post(new Runnable() {
public void run() {
//ScrollView.FOCUS_DOWN if you want to scroll down
//ScrollView.FOCUS_UP if you want to scroll up
svComments.fullScroll(ScrollView.FOCUS_DOWN);
}
});

Categories