I am using following layout
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/lnrLayout_cVideo_LB"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:orientation="vertical">
<RelativeLayout
android:id="#+id/relative_cVideo_LB"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight=".15" >
<VideoView
android:id="#+id/cVideo_LB"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:tag="2" />
</RelativeLayout>
<TextView
android:id="#+id/txtVw_cVideo_LB"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight=".85"
android:background="#FFFFFF"
android:gravity="center"
android:text=""/>
</LinearLayout>
So when I click on VideoView position of TextView should go to top of VideoView when I click again, I should restore.
For that I am using following code,
video.setOnTouchListener(new OnTouchListener() {
#Override
public void onTouch(View v) {
// TODO Auto-generated method stub
if(flag_video==0)
{
textview.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT,(float).85);
relative_LB.setLayoutParams(new LayoutParams(android.widget.RelativeLayout.LayoutParams.MATCH_PARENT,android.widget.RelativeLayout.LayoutParams.MATCH_PARENT,(float).15);
flag_video=1;
v.invalidate();
}
else
{
relative_LB.setLayoutParams(new LayoutParams(android.widget.RelativeLayout.LayoutParams.MATCH_PARENT,android.widget.RelativeLayout.LayoutParams.MATCH_PARENT,(float).15));
lb.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT,(float).85));
flag_video=0;
v.invalidate();
}
}
});
But it is not changing its position. I explored solution, I found that I can do it by View.removeView() and View.addView() method. But for my application purpose I can't use those methods. So anybody suggest me an alternate way??
Please dont suggest me View.removeView() and view.addView() methods
You have two problems:
You are using onTouch(View v) method instead of onTouch(View v, MotionEvent event) method. onTouch() method should have tow parameter. 2. Return type of onTouch() should be boolean type but you are using void.
Another problem is that you are setting LayoutParams to lb instead to textview in the else condition.
Now, replace the following listener code snippet with yours...I think, you will get it right.
video.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
if (flag_video == 0) {
textview.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT, (float) .85));
relative_LB.setLayoutParams(new LayoutParams(
android.widget.RelativeLayout.LayoutParams.MATCH_PARENT,
android.widget.RelativeLayout.LayoutParams.MATCH_PARENT, (float) .15));
flag_video = 1;
v.invalidate();
} else {
relative_LB.setLayoutParams(new LayoutParams(
android.widget.RelativeLayout.LayoutParams.MATCH_PARENT,
android.widget.RelativeLayout.LayoutParams.MATCH_PARENT, (float) .85));
textview.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT, (float) .15));
flag_video = 0;
v.invalidate();
}
return true;
}
});
You can set the visibility of the RelativeLayout to GONE, it should disappear and the textview go upside, like the following method (when the flag_video == 0 the textview go up):
video.setOnTouchListener(new OnTouchListener() {
#Override
public void onTouch(View v) {
// TODO Auto-generated method stub
if(flag_video==0)
{
//textview should go upside
relative_LB.setVisibility(RelativeLayout.GONE);
flag_video=1;
}
else
{
relative_LB.setVisibility(RelativeLayout.VISIBLE);
flag_video=0;
}
}
});
Hope it helps!
Related
I'm trying to make an HoziontalScrollView with items :
When I move the scrollbar to the left, the HoziontalScrollView goes right and vice versa, which will make the user confused about how to use the scrollbar to scroll instead of moving finger over the HoziontalScrollView
XML :
<HorizontalScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:fadeScrollbars="false"
android:scrollbarStyle="outsideInset"
android:scrollbarThumbHorizontal="#drawable/outer_windows_background"
android:scrollbarTrackHorizontal="#drawable/scrollbar_track_horizontal"
tools:showIn="#layout/activity_photo_editor">
//ITEMS
</HorizontalScrollView>
Thank you.
Try this :
HorizontalScrollView hsv;
hsv.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
event.setLocation(-1*event.getX(), event.getY());
hsv.dispatchTouchEvent(ev);
return true;
}
})
I'm trying to subclass MediaController in order to make it fully customizable (I'm not going with vidtry approach because I have some legacy code that I can't change).
My code looks roughly like this:
mc_layout.xml:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<LinearLayout
android:id="#+id/top"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
...>
// Some buttons
</LinearLayout>
<LinearLayout
android:id="#+id/bottom"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
... >
// Some buttons
</LinearLayout>
mc_subclass.java:
public class MCSubclass extends MediaController {
private View mRoot;
GestureDetector mGestureDetector = new GestureDetector(getContext(), new SimpleOnGestureListener() {
#Override
public boolean onDown(MotionEvent e) {
// Do something.
return true;
}
#Override
public boolean onSingleTapConfirmed(MotionEvent e) {
// Do something.
return true;
}
#Override
public boolean onDoubleTap(MotionEvent e) {
// Do something.
return false;
}
});
public MCSubclass(final Context context) {
super(context);
}
public boolean onTouchEvent(final MotionEvent event) {
// NEVER CALLED!
return mGestureDetector.onTouchEvent(event);
}
public final void setAnchorView(final View view) {
super.setAnchorView(view);
FrameLayout.LayoutParams frameParams = new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
);
removeAllViews();
View v = makeControllerView();
addView(v, frameParams);
}
private View makeControllerView() {
LayoutInflater inflate = (LayoutInflater) getContext().getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
mRoot = inflate.inflate(R.layout.mc_layout, null);
initControllerView(mRoot);
return mRoot;
}
private void initControllerView(View v) {
mPlayButton = (ImageButton) v.findViewById(R.id.playBtn);
if (mPlayButton != null) {
mPlayButton.requestFocus();
mPlayButton.setOnClickListener(mOnClickListener);
}
// Init other views...
}
}
Now, I got all controls visible and they're all responding to their's click/touch actions but when I click/touch the MC window instead of invoking an overridden onTouchEvent as I expected the MediaController's onTouch of a decor window got called as it can be seen in the callstack:
MediaController$1.onTouch(View, MotionEvent) line: 149
PhoneWindow$DecorView(View).dispatchTouchEvent(MotionEvent) line: 3762
PhoneWindow$DecorView(ViewGroup).dispatchTouchEvent(MotionEvent) line: 897
PhoneWindow$DecorView.dispatchTouchEvent(MotionEvent) line: 1862
ViewRoot.handleMessage(Message) line: 1809
ViewRoot(Handler).dispatchMessage(Message) line: 99
Looper.loop() line: 123
The question is do I need to replace the decor window touch listener or there is a better way and I'm missing something?
p.s. I'm working with lv. 9 API.
Thanks!
I found it!
The problem is in using FrameLayout which can display only a single item and whose size is the size of a largest child. So in my case it was not large enough to cover the whole screen as I expected. As the result, the decor window ended up handling the touch event which make perfect sense.
Anyway the working layout now looks like:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:id="#+id/top"
android:layout_width="match_parent"
android:layout_height="wrap_content"
...>
// Some buttons
</LinearLayout>
<LinearLayout
android:id="#+id/bottom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
... >
// Some buttons
</LinearLayout>
....
</RelativeLayout>
Hope this will help one day to someone:)
I can't get onTouch event triggered on a container when clicking on its ScrollView child.
I'm using API 12 on a Galaxy tab 10.1.
Anybody can help?
Thanks
Activity
public class TestActivity extends Activity{
#Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.dude);
LinearLayout mylayout = (LinearLayout) findViewById(R.id.mylayout);
mylayout.setOnTouchListener(new OnTouchListener () {
public boolean onTouch(View view, MotionEvent event) {
// Only called when touched outside the ScrollView
if (event.getAction() == android.view.MotionEvent.ACTION_DOWN) {
/* do stuff */
} else if (event.getAction() == android.view.MotionEvent.ACTION_UP) {
/* do stuff */
}
return true;
}
});
}
}
Layout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/mylayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
android:orientation="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="200dp"
android:gravity="center"
android:text="Touch here trigger parent's onTouch"
android:textColor="#000000"
android:textSize="40sp" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:layout_width="match_parent"
android:layout_height="1000dp"
android:background="#b00000"
android:gravity="center"
android:text="Touch here DOES NOT trigger parent's onTouch"
android:textColor="#000000"
android:textSize="40sp" />
</RelativeLayout>
</ScrollView>
</LinearLayout>
mylayout.setOnTouchListener(new OnTouchListener () {
public boolean onTouch(View view, MotionEvent event) {
// Only called when touched outside the ScrollView
if (event.getAction() == android.view.MotionEvent.ACTION_DOWN) {
/* do stuff */
return true;
} else if (event.getAction() == android.view.MotionEvent.ACTION_UP) {
/* do stuff */
return true;
}
return false;
}
});
this should work... but you no longer have auto-scroll when you fling it hard... it'll be a sticky scroll moving only as much as you drag.
Did u try to create ONE OnClickListener and add it to all childs?
Maybe this could solve your
As the ScrollView makes it childs scrollable it wouldn't have an own area to click in.
(Correct me if I'm wrong ^^)
You probably need this code
#Override
public boolean onInterceptTouchEvent(MotionEvent ev)
{
onTouchEvent(ev);
return false;
}
I have this main.xml file:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/background"
>
<ImageView
android:id="#+id/img1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/z01"
/>
<ImageView
android:id="#+id/img2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/z02"
/>
</LinearLayout>
What I am trying to achieve is:
when the user touch and hold img1, the picture changs to the pressed pic (i.e. changed from z01.png to z01_pressed.png)
when (for example) the user moves from img1 to img2 while he holding, img2 get pressed (changed its picture from z02.png to z02_pressed.png) and img1 returns to its state (to z01.png).
to achieve this, I wrote this in onCreate method:
final ImageView img1 = (ImageView) findViewById(R.id.img1);
final ImageView img2 = (ImageView) findViewById(R.id.img2);
img1.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
img1.setBackgroundResource(R.drawable.z01_pressed);
return false;
}
});
img2.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
img2.setBackgroundResource(R.drawable.z01_pressed);
return false;
}
});
However, this does not work. Am I getting something wrong?
You can use a button and set a custom image as the drawable of that button. That way, you won't have to manage the pressed and unpressed states yourself. See this link:
http://blog.androgames.net/40/custom-button-style-and-theme/
To those who might be interested:
This can be done using OnDragListener. It needs some work to accomplish this. I gave up on that to make my life easier.
I want to display a TextView just above thumb of the SeekBar that will display the current progress of seek bar. As we move the thumb forward and backward the TextView will also move with thumb (the TextView should also be above the thumb).
Please provide any clue, code snippet are always welcome.
Moving the text can even more easily done by setting the padding for the TextView as:
int xPos = ((SeekbarInstance.getRight() - SeekbarInstance.getLeft()) * SeekbarInstance.getProgress()) / SeekbarInstance.getMax();
textViewInstance.setPadding(xPos, 0, 0, 0);
Layout of your activity
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<!-- Main context -->
<LinearLayout android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<SeekBar android:id="#+id/skbSample"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dip"
android:layout_marginRight="10dip"
android:max="35">
</SeekBar>
</LinearLayout>
<!-- For display value -->
<AbsoluteLayout android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:text="0"
android:id="#+id/txvSeekBarValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFFFFFFF"
android:background="#FF777777"
android:visibility = "invisible">
</TextView>
</AbsoluteLayout>
</FrameLayout>
Initialize your controls on create:
mTxvSeekBarValue = (TextView) this.findViewById(R.id.txvSeekBarValue);
mSkbSample = (SeekBar) this.findViewById(R.id.skbSample);
mSkbSample.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN)
{
ShowSeekValue((int)event.getX(), mTxvSeekBarValue.getTop());
mTxvSeekBarValue.setVisibility(View.VISIBLE);
}
else if(event.getAction() == MotionEvent.ACTION_MOVE)
{
ShowSeekValue((int)event.getX(), mTxvSeekBarValue.getTop());
}
else if(event.getAction() == MotionEvent.ACTION_UP)
{
mTxvSeekBarValue.setVisibility(View.INVISIBLE);
}
return false;
}
});
Function will move your value:
private void ShowSeekValue(int x, int y)
{
if(x > 0 && x < mSkbSample.getWidth())
{
AbsoluteLayout.LayoutParams lp = new AbsoluteLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, x, y);
mTxvSeekBarValue.setLayoutParams(lp);
}
}
Found a better way. Derived from the sample:
mTxvSeekBarValue = (TextView) this.findViewById(R.id.txvSeekBarValue);
mSkbSample = (SeekBar) this.findViewById(R.id.skbSample);
mSkbSample.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN)
{
int progress = mSkbSample.getProgress();
mTxvSeekBarValue.setText(String.valueOf(progress).toCharArray(), 0, String.valueOf(progress).length());
}
else if(event.getAction() == MotionEvent.ACTION_MOVE)
{
int progress = mSkbSample.getProgress();
mTxvSeekBarValue.setText(String.valueOf(progress).toCharArray(), 0, String.valueOf(progress).length());
}
return false;
}
});
There you don't need any additional method and the ACTION_UP event has no important effect on the result.