Hello I have a ImageView(background) which's height should correspond to the screen height, the width on the other hand should be left intact.
Before this was done like this
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="match_parent">
<HorizontalScrollView
android:layout_width="wrap_content"
android:layout_height="match_parent">
<ImageView
android:id="#+id/songDetails_songImage"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:adjustViewBounds="true"
android:contentDescription="#string/songDetails_cd_songCover"
app:srcCompat="#drawable/default_song_cover" />
</HorizontalScrollView>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
...
This worked fine - the image view occupies whole background and the user can scroll right or left to see the whole image.
My goal is to animate the scroll, to do that I need to get rid of the horizontal view(to prevent user from scrolling) but whenever I change the HorizontalScrollView to Frame/Relative layouts(with the width set to wrap_content) the image view is scaled down to fit the screen.
Is there a way to keep the imageView width intact(with height matching that of the screen) so that it would remain bigger than the device screen?(without cropping)
I could then use custom animation to scroll right.
I have looked at similar questions but I wasn't able to find anything that would work in this case.
What you could do is to try to override the onTouchListener for the HorizontalScrollView.
For example, something like this:
scrollView.setOnTouchListener(new OnTouch());
private class OnTouch implements OnTouchListener
{
#Override
public boolean onTouch(View v, MotionEvent event) {
return true;
}
}
This would disable the user from scrolling the HorizontalScrollView while you could probably still scroll it programmatically.
Related
I have been trying to put a button on top of an image in a specific area. So, the button will stick to the specific area in the image even if the device is rotated or in different screen sizes.
So far i have tried a couple of things but none of them seems working as when i rotate the device then the button moves to another area.
1. I tried to draw a rectangle using specific coordinates but on device rotation the rectangle moves to another area. Below is the code:
ArrayList<Rect> mAreas = new ArrayList<>();
mAreas.add(new Rect(0,0,200,200));
mAreas.add(new Rect(300,0, 500, 300));
mImageView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
for (final Rect cRect : mAreas) {
if (cRect.contains(event.getX(), event.getY())) {
Toast.makeText(getContext(), "AREA TOUCHED!!", Toast.LENGTH_SHORT).show();
return true;
}
}
return false;
}
});
2. also tried with constraintlayout and again the button moves to another place:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:id="#+id/imgvw4"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/cartoon"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"/>
<Button
android:text="Button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/button_4"
app:layout_constraintTop_toTopOf="#+id/imgvw4"
app:layout_constraintBottom_toBottomOf="#+id/imgvw4"
app:layout_constraintLeft_toLeftOf="#+id/imgvw4"
app:layout_constraintRight_toRightOf="#+id/imgvw4"
app:layout_constraintVertical_bias="0.25"
app:layout_constraintHorizontal_bias ="0.5" />
</android.support.constraint.ConstraintLayout>
How do i solve it? Lets say in the below image- in want to have a button which will be on top of the eyes. Please help me with some guidelines or references.
Have you tried to use Linear Layout or Relative Layout.
In Linear Layout make the orientation Vertical and put the button above and then the image or u can use relative layout and then add the attribute layout_alignParentTop =true in the button. The button will remain at the top.
Hope this solves ur question.
I have a layout that contains a ListView and a few buttons in a RelativeLayout. I am trying to let the user draw on the page using a custom paint view layout. The good news is that I've got nearly everything working and looking how it should, however the last and most frustrating issue is that the ListView is no longer clickable at all. I would like to paint on top of the the ListView AND make it clickable.
The funny part is that the buttons on the page are still clickable, just the items in the ListView are not. I think what is happening is that the ListView is loaded by an adapter and gets loaded first (thus behind everything). What do I need to do in order to make the ListView clickable?
I've tried adding android:focusableInTouchMode="true" android:focusable="true" but it made no difference.
My layout is as follows:
<?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:background="#drawable/background"
android:orientation="vertical" >
<ListView android:id="#+id/lv"
android:layout_height="match_parent"
android:layout_width="match_parent"
></ListView>
<com.my.app.PaintView
android:id="#+id/paintView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<Button
Buttons Here.../>
</RelativeLayout>
The focusable attribute should be false for the element you do not want to receive touch events. To overlay your PaintView without having it intercept touch events, you can add a few XML attributes to it:
<com.my.app.PaintView
...
android:focusable="false"
android:clickable="false" />
As long as you don't set an OnClickListener or an OnTouchListener to your PaintView, touch events should simply pass through it to the Views behind it.
Managed to find a solution that works perfectly (at least for me). I imagine without the listview this would have been far easier, but I wanted the listview to work as well as drawing on the canvas. All I ended up having to do was set an onTouchListener in the main activity that had the ListView, then send it to the PaintView with the MotionEvent. Simple and it works perfectly:
listview.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
paintView.onTouchEvent(motionEvent);
return false;
}
});
In this example, the paintView.onTouchEvent could really be any method in the custom view, just kept it at "onTouchEvent" for simplicity.
I am new to android and trying to create an application in native android.
I have a top bar which is 10% height of the whole screen and full width. Initially I want to show the bar when application launch. When user drag the application downwards, need to animate the "top bar" to -10%, so that user can't view. Also when user drag screen upwards then need to animate the "top bar" to 0, ie beginning of the screen ( normal position ).
So I have my layout like this
<relativelayout>
<linearLayout>
// Top bar content here
<linearLayout>
<linearLayout>
// With list items, etc
</linearLayout>
</relativelayout>
I am stuck on that animation part. How to get the events and do the animation.
Please give me a hint.
Thanks in advance
You could create an onTouch() method where the View is the whole screen. Specify what you want the top bar to do depending on the touch motion. Here's some code to start:
public boolean onTouch(View v, MotionEvent evt) {
switch(evt.getAction()){
case MotionEvent.ACTION_DOWN:
// your code that makes it disappear
return true;
case MotionEvent.ACTION_UP:
// your code that makes it reappear
return true;
}
return false;
}
In your xml, add ids to your layout.
<LinearLayout
android:id="my_layout"
android:layout_height="fill_parent"
android:layout_width="fill_parent">
<TextView
android:id="topbar"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:layout_weight="1">
<ListView
android:id="list"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:layout_weight="9">
</LinearLayout>
The ids will be what you call upon in your onTouch() method to change the layout weight, or percentage of the top bar, from 1 to 0 and vice versa at your discretion.
Look into the first answer for an algorithm for figuring out whether the touch event scrolled up or down.
I have to add pull-to-refresh functionality to refresh info on main screen. Here`s a scheme of my screen UI (red area should handle pulling):
I use ready solution for pull-to-refresh. Due to documentation, my red layout should be one of these classes:
ListView
ExpandableListView
GridView
WebView
ScrollView
HorizontalScrollView
ViewPager
But I have ListView on my screen, so I am not able to use ScrollView as red layout. And I`m stuck with this problem. It is possible to use UITableView into UIScrollView in iOS, but in Android one I have no idea what to do in such cases.
Any help will be appreciated. Thanks!
Why not replace the listview by a LinearLayout and then you can use the ScrollView?
You just need to create a layout for the items in the linearlayout and then adding them using something like this:
LinearLayout layout = (LinearLayout)findViewById(R.id.MyListLayout);
for (int i=0; i<list.size(); i++) {
Item item = list.get(i);
View view = inflater.inflate(R.layout.MyRowLayout, null);
Textview myTextView = view.findViewById(R.id.MyTextView);
myTextView.setText(item.getString());
list.addView(vi);
}
Is the pull-to-refresh horizontal or vertical?
In case it's horizontal, use a HorizontalScrollView (a ViewPager would do, too), and then place a Table?Layout inside it.
In case it's horizontal, well, I don't think I like that design (the pull-to-refresh area should just be the ListView), but I believe there is some way to use the ListView without its internal scrolling so that you can rely on a parent ScrollView to do the scrolling, but I'd need to check the code of an old problem to "remember" how to do that.
I've solved this issue, but forgot to write about it :)
My layout.xml file looks like this:
<com.handmark.pulltorefresh.library.PullToRefreshScrollView
android:id="#+id/home_info_pulltorefresh"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true" >
<LinearLayout
android:id="#+id/home_info_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/white_background"
android:baselineAligned="false"
android:orientation="horizontal" >
<LinearLayout
android:id="#+id/charts_container"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
android:orientation="vertical"
android:paddingRight="5dp" >
<FrameLayout
android:id="#+id/frame_container_chart_top"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<FrameLayout
android:id="#+id/frame_container_chart_bottom"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
<FrameLayout
android:id="#+id/frame_container_right"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
</LinearLayout>
</com.handmark.pulltorefresh.library.PullToRefreshScrollView>
android:fillViewport="true" is used to stretch its content to fill the viewport (make height of scroll match_parent)
I add Fragment containing ListView programmatically (R.layout.frame_container_right Fragment resource ID)
Everything worked fine, but when I tried to scroll ListView down, my ScrollView began to scroll. Scrolling ListView up worked fine. Also I noticed that if I tap ListView, move finger left or right and then try to scroll down, touch events are not transmitted from ListView to ScrollView and I get expected behavior. So I've decided to emulate this situation programmatically:
mListViewReviews.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
long startTime = SystemClock.uptimeMillis();
long duration = 1;
MotionEvent e = MotionEvent.obtain(startTime, startTime + duration, MotionEvent.ACTION_MOVE, event
.getX(), event.getY() + 10, 0);
MotionEvent ev = MotionEvent.obtain(startTime + duration, startTime + duration * 2,
MotionEvent.ACTION_MOVE, event.getX(), event.getY() + 20, 0);
v.dispatchTouchEvent(e);
v.dispatchTouchEvent(ev);
}
return false;
}
});
As a result, I've got working ListView with proper cell reuse and working pull-to-refresh logic. Thanks!
I'm having some trouble with detecting screen clicks on the GUI. Works in portrait but fails in landscape, see below.
I have a GUI (Fragment) which contains some instructions + images. The user is required to tap anywhere on the screen to proceed. In order capture the click/tap event, I have put in a View(topview) that fill the entire screen and sits onto of other elements, I then listen for clicks on this view and it works fine.
The problem is when in landscape mode, the text and images take up to much room. So the whole thing is now wrapped in a ScrollView. This is where the problem begins. When the ScrollView is active, (i.e. you can scroll/scroll bars are visible), my view on top (topview) disappears. It seems that when in landscape mode the height of content in a ScrollView is being changed. As an experiment I replaced the View with a Button and the Button goes from filling the screen in portrait to being normal height in landscape mode when the ScrollView is usable.
Is there a way of me detecting the user tapping on the screen, which works with the ScrollView control as the top element. I've tried rearranging the GUI in several ways but without success, and I've tried adding onClick event handlers to the ScrollView, also without success.
My Layout is below, note my top view is semi-transparent red, so I could see the area it covered.
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:clickable="true" >
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:orientation="vertical" >
<TextView
android:id="#+id/txtInstructions"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal|center_vertical"
android:padding="10dp"
android:text="#string/instructions"
android:textColor="#color/blue"
android:textSize="20sp" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:adjustViewBounds="true"
android:maxWidth="250dp"
android:padding="20dp"
android:src="#drawable/main_camera" />
</LinearLayout>
<View
android:id="#+id/view_to_listen_for_touch"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#88FF0000"
android:clickable="true" />
</RelativeLayout>
One thing that works(although looks like more like a hack(pretty ugly)) is to programatically add the special View in code(in the onCreate method) and set its dimensions based on the parent RelativeLayout's exact dimensions. Here is a snippet of code:
//...
final RelativeLayout parent = (RelativeLayout) findViewById(R.id.ff);
final View layer = new View(this);
layer.setBackgroundColor(Color.parseColor("#88FF0000"));
// the ScrollView really doesn't like this View ,using this without the
// runnable will not work
layer.setLayoutParams(new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT,
RelativeLayout.LayoutParams.MATCH_PARENT));
layer.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getApplicationContext(), "SDFD",
Toast.LENGTH_SHORT).show();
}
});
parent.addView(layer);
// this is required because if we use directly the getWidth/getHeight we
// will get 0/0
layer.post(new Runnable() {
#Override
public void run() {
layer.setLayoutParams(new RelativeLayout.LayoutParams(parent
.getWidth(), parent.getHeight()));
}
});
//...