I have custom view,When loading this view I am drawing bitmap into canvas this bitmap drawn based on pdf pages length and size.And I am providing 2 buttons to user for drawing paths and drawing text on canvas.
For adding this View into my parent in two ways :
1 . Creating child layout(LinearLayout or RelativeLayout) inside parent layout and programatically adding Scroller in CustomView and adding custom view into childLayout.
xml Layout :
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/custom_pdf_viewer_parent_relative_layout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:id="#+id/custom_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
</LinearLayout>
/RelativeLayout>
2. Creating child layout (ScrollView inside Horizontal Scrollview) inside Parent layout and adding custom view into childLayout(ScrollView).
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<com.pakagename.CustomHorizontalScrillView
android:id="#+id/pages_horizontal_scroll"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/top_buttons_layout"
android:fillViewport="true" >
<com.pakagename.CustomVerticalScrollView
android:id="#+id/pages_vertical_scrollview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true" />
</com.cudrivepdfeditor.CustomHorizontalScrillView>
</RelativeLayout>
And for adding scroll into canvas I am using onMeasure(int widthMeasureSpec, int heightMeasureSpec).
In first case :
But this onMeasure is not working in first case. Because custom view is added into LinearLayout.But by programatically I am adding scroller into custom view.I don't know why onMeasure is not working.But in debugging mode widthMeasureSpec,heightMeasureSpec are not null and not 0 those have different values what exactly file have.
In second case :
In this case I am adding custom view into my verticalscrollview this verticalscrollview placed in horizantalscrollview.In this case onMeasure() method calls multiple times and it's adding scroll into customview and canvas.Canvas content also scrolls when I am scrolling.
But In my case I have zooming functionality also.When I click on zoom++ button canvas is not zooming and onMeasure() also not giving proper width and height.
in my zoom++() I called measure(requiredWidth, requiredHeight) method.
How I can scroll and zoom canvas content?Any one have any idea please help me.I stuck in this functionality from very long time.
Edit#1 :
#Override
public void onDraw(Canvas canvas) {
drawPages(canvas); // This drawPages(canvas) method draw a pages on canvas
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
this.width = w;
this.height = h;
mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap); // Here I am creating new bitmap on canvas and I am drawing paths and text on this canvas.
}
Here my problem was when I am drawing paths on canvas of onDraw() it's draw a paths but when I touch up that paths are rest.And if I draw a path on mCanvas it's drawing paths and it's not resetting.But how I can scroll this mCanvas with onDraw() canvas.
Related
In a game I display a custom View and a FAB in a FrameLayout:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<de.slova.GameView
android:id="#+id/gameView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_marginBottom="16dp"
android:layout_marginRight="16dp"
android:src="#drawable/play_white" />
</FrameLayout>
However the FAB is shown too low and obscures the light blue bar at the bottom:
I need to increase the layout_marginBottom by the height of the light blue bar (indicated by the red arrows at the above screenshot), so that the FAB is moved up.
I do know the height of the bar in pixels (the content of my custom View is scaled by a Matrix) and I think I know the right place for this action (the onSizeChanged method in my custom View) - but my difficulty is getting ahold of the FAB's layout_marginBottom value.
How to access and change it please? I have tried:
#Override
protected void onSizeChanged(int w, int h, int oldW, int oldH) {
super.onSizeChanged(w, h, oldW, oldH);
int h = mBar.getHeight();
ViewGroup.LayoutParams params = mFab.getLayoutParams();
// how to add h to layout_marginBottom here?
mFab.setLayoutParams(params);
}
By the way I do have two methods to translate between dp and px if needed here:
public static float px2sp(Context context, float px) {
float scaledDensity = context.getResources().getDisplayMetrics().scaledDensity;
return px / scaledDensity;
}
public static float sp2px(Context context, float sp) {
float scaledDensity = context.getResources().getDisplayMetrics().scaledDensity;
return sp * scaledDensity;
}
Margin property is part of FrameLayout.LayoutParams Class, so you have to cast it to FrameLayout.LayoutParams
FrameLayout.LayoutParams param = (FrameLayout.LayoutParams) fab.getLayoutParams();
param.bottomMargin = mBar.getHeight();
fab.setLayoutParams(param);
I'm using the AutoResizeTextView class found here. Auto Scale TextView Text to Fit within Bounds and it works great. However, I have the textview in a RelativeLayout and I have the layout_centerVertical property on the TextView set to true. Works great, unless the TextView doesn't fit and resizes itself. Then the text is no longer vertically centered within the RelativeLayout.
I'm guessing this is because the vertical alignment is performed BEFORE the TextView does its resizing.
How can I fix this? Is there a way to re-trigger the gravity alignment of the View after the text is resized?
Example layout
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp">
<com.mypackage.android.AutoResizeTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Some Text Here"
android:maxLines="1"
android:ellipsize="end" />
</RelativeLayout>
Try to also trigger resizeText() in
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// trigger here
}
//This is called during layout when the size of this view has changed
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
// trigger here
}
My problem is that if i set the Y-axis of my view to anything but 0 its drawn region gets clipped from the top. Using log traces i've discovered that the view bounds (and its drawable's bounds) are always the correct position. I've tried clipChildren=false, but that gave me a stranger behavior where the drawn region and the views bounds are not in sync. Here's all pertinent code to my view
//onMeasure
#Override
public void onMeasure(int w, int h){
int width = MeasureSpec.getSize(w);
//minHeight is 48dp scaled for density
setMeasuredDimension(width, minHeight);
}
//onDraw
//Note that i've ommited the log statements, however they return the correct
//coordinates for the view Rect
#Override
public void onDraw(Canvas c){
c.drawRect(trackRect, tempPaint);
}
//onLayout
#Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
trackRect.set(left, top, right, bottom);
mTrack.setBounds(trackRect); //irrelevant atm
}
//XML CODE
//BELOW draws a perfect rectangle with a width of match_parent and a height
//of 48dp
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false" >
<com.bryanstudios.bryan.clock.LocationSwitch
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</RelativeLayout>
//BELOW will cause clipping
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false">
<com.bryanstudios.bryan.clock.LocationSwitch
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</RelativeLayout>
//BELOW causes the view to disappear entirely
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false">
<com.bryanstudios.bryan.clock.LocationSwitch
android:align_parent_bottom="true"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</RelativeLayout>
My best guess is my onMeasure isn't done properly. Also note again that regardless of where i position the view (via w/ margins or LayoutParam attributes) the logical positioning of the view is accurate, yet the drawn region is not.
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
trackRect.set(left, top, right, bottom);
...
The left/top/etc params here are relative to the parent. If your view's y position == 0, top also == 0. If you change the view's Y position relative to its parent, top is set to that same value. You are then assigning this top to the rect you draw.
public void onDraw(Canvas c){
c.drawRect(trackRect, tempPaint);
...
This will draw a rectangle with the same offsets you have specified in onLayout. This means that it will begin drawing trackRect.top from the top of the view.
If you just want the actual size of the view, view.getWidth() and view.getHeight() are likely all that is needed; if you want to initialise something (like a Path) when the width and height of the view are known, override onSizeChanged() and do it in there instead of in onLayout().
I have a layout displaying some images and text, with buttons at the bottom.
When a button is pressed, I need to display some new information below the buttons.
So the initial content needs to remain at the same height (height of the device screen), and the new content needs to be added beneath it, allowing the user to scroll down.
When a button is pressed it will ideally need to show the new content like a page anchor, but the part I'm having difficulty is getting the initial content to be fullscreened, and maintain that size when new content is added whilst also making the whole thing scroll-able.
I have been playing with different layouts, different height parameters, android:fillViewport="true" or not etc.
I can provide some XML / further explanation if necessary. But I'm not sure whether what I am aiming to achieve is possible or not. At least I'd like to get a scrollable overall view, with the top layout as fullscreen and some layouts underneath which the user can scroll to.
image:
Try this:
Make ScrollView container and add your layout #1 into it
Set height of layout #1 into the code according per screen height
After button click add layout #2 into ScrollView
UPDATED:
Ok, I can suggest you only this solution (it worked for me in emulator).
XML:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/scroll"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<LinearLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:id="#+id/layout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ff0000">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
android:onClick="btnClick"/>
</RelativeLayout>
</LinearLayout>
</ScrollView>
Code:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void btnClick(View v){
LinearLayout container = (LinearLayout)findViewById(R.id.container);
ScrollView scroll = (ScrollView)findViewById(R.id.scroll);
RelativeLayout layout1 = (RelativeLayout)findViewById(R.id.layout1);
RelativeLayout layout2 = new RelativeLayout(this);
LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, 300);
layout2.setBackgroundColor(Color.YELLOW);
layout1.getLayoutParams().height = scroll.getHeight();
scroll.setFillViewport(false);
container.addView(layout2, params);
}
}
I would create a custom ScrollView which sets the height of its first child to be its own height. This will simulate a fullscreen view while still being able to add content below it.
To handle screen size changes properly, the best is to override onSizeChanged() :
public class CustomScrollView extends ScrollView {
// ...
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
View view = getChildAt(0);
if (view != null)
view.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, h)));
}
}
I've been searching a lot, but I can't get a solution for my problem. I can't use android:rotation as I want this app to be compatible with Android API under 11 version.
My problem is something similar to this: Rotating a view in Android
I've done this:
#Override
public void draw(Canvas canvas) {
canvas.save();
Drawable d = getDrawable();
canvas.rotate(-10, d.getIntrinsicWidth() / 2, d.getIntrinsicHeight() / 2);
super.draw(canvas);
canvas.restore();
}
The ImageView is part of a RelativeLayout where I place the image and some text.
But the image is cropped in the edges. How can I avoid that?
You simply have to add:
android:clipChildren="false"
to the parent ViewGroup.
For Example:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
android:layout_width="300dp"
android:layout_height="300dp"
android:clipChildren="false">
<com.yourcompany.views.RotateImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:background="#android:color/white"
android:src="#drawable/ic_launcher" />
</FrameLayout>
RotateImageView:
public class RotateImageView extends ImageView {
#Override
public void draw(Canvas canvas) {
canvas.save();
int height = canvas.getHeight();
int width = canvas.getWidth();
canvas.rotate(45, height / 2, width / 2);
super.draw(canvas);
canvas.restore();
}
}
Which provides a clean solution before API Level 11
Try adding your ImageView as a child view of a FrameLayout and set the FrameLayouts width and height the same as that of your ImageView. View my similar answer here. Original answer relayed from a post by Pavlo Viazovskyy here. Hope this helps!