AndroidPlot is an awesome lib.
I followed http://androidplot.com/docs/how-to-pan-zoom-and-scale/ to make a scrollable chart but found the domain grid lines were fixed while the chart was scrolling. Is it possible to make the grid lines scroll with the chart?
Thanks
I wrapped my graph in a linear layout:
<LinearLayout
android:id="#+id/graphLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<com.androidplot.xy.XYPlot
android:id="#+id/mySimpleXYPlot"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
....
Then in the .java file I assigned the view to the linear layout and set the onTouchListener to that layout:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_graph);
LinearLayout view = (LinearLayout) findViewById(R.id.graphLayout); // assign layout graph is in
view.setOnTouchListener(this); // set onTouchListener to graph's layout
plot = (XYPlot) findViewById(R.id.mySimpleXYPlot);
....
That worked for me.
Related
Why doesn't textView21.SetLeftTopRightBottom(1,200,45, 275) change the size of a textview?
<TextView
android:id="#+id/textView21_id"
android:layout_width="60dp"
android:layout_height="wrap_content"
android:layout_x="22dp"
android:layout_y="105dp"
android:height="50dp"
android:gravity="center"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text=""
android:textSize="30sp"
android:textColor="#000000"
android:background="#9999cc"
android:singleLine="false"/>
There's the activity_main.xml snippet. Is there something there which overrides the SetLeftTopRightBottom?
I am still trying to get two different but ordinary mobile phones (cell phones) to display a view the same.
pic of same app in two phones
You can see the left hand pic shows to below the grey '6:' textview and includes the 'Go' textview and all the right hand 5th-letter-in-the-word textview areas whereas the other pic doesn't.
I've figured out how to get each phone's display metrics
var metrics = Resources.DisplayMetrics;
gnumWidthDp = ConvertPixelsToDp(metrics.WidthPixels);
gnumHeightDp = ConvertPixelsToDp(metrics.HeightPixels);
I thought it would be easy to do the SetLeftTopRightBottom thing and set each textview in the right place.
Please can you tell me what I have missed? Thank you all.
In the official document, SetLeftTopRightBottom method is meant to be used in animations only as it applies this position and size for the view only temporary and it can be changed back at any time by the layout.
More information: https://developer.android.com/reference/android/view/View#setLeftTopRightBottom(int,%20int,%20int,%20int)
In addition, the size of the textview21 had been ensured in the xml. If you want to set the size of it dynamically, you need to use the LayoutParams. Such as:
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(300, 200);
//300 is width and 200 is height
textView.LayoutParameters = layoutParams;
I'm trying to set a custom actionbar background but it does not fill up the entire space.
it leaves like a 5dp grey actionbar from left side.
I used the following:
android.support.v7.app.ActionBar.LayoutParams layout = new android.support.v7.app.ActionBar.LayoutParams(android.support.v7.app.ActionBar.LayoutParams.FILL_PARENT, android.support.v7.app.ActionBar.LayoutParams.FILL_PARENT);
getSupportActionBar().setCustomView(view, layout);
getSupportActionBar().setDisplayShowCustomEnabled(true);
this is my custom actionbar xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="fill_horizontal"
android:background="#color/actionbar_color"
></RelativeLayout>
I have tried different styles but none worked.
please help
fixed it by doing:
//to set same background color on entire actiobar
getSupportActionBar().setBackgroundDrawable( getResources().getDrawable(R.drawable.actionbar_color));
//to display custom layout with same BG color
android.support.v7.app.ActionBar.LayoutParams layout = new android.support.v7.app.ActionBar.LayoutParams(android.support.v7.app.ActionBar.LayoutParams.FILL_PARENT, android.support.v7.app.ActionBar.LayoutParams.FILL_PARENT);
getSupportActionBar().setCustomView(view, layout);
getSupportActionBar().setDisplayShowCustomEnabled(true);
I am having a strange problem. I scale an image and, while scaling works correctly, the image always gets clipped. I tried different scale types - things changed but I never could make it work.
Just to be clear, here's what I need to solve:
1. I have a HorizontalScrollView around the ImageView and a ScrollView around the HorizontalView.
2. I scroll around (using scrollTo of both scroll views) and, upon a certain event, zoom in.
3. What I'd like to happen is for the ImageView to scale around my current scroll position.
Here's the layout:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="none"
android:overScrollMode="never">
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="none"
android:overScrollMode="never">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:scaleType="fitCenter" />
</HorizontalScrollView>
</ScrollView>
</FrameLayout>
And here's the scaling code (originalWidth/originalHeight are calculated at scale of 1; targetView points to the ImageView):
public synchronized void changeScale(float newScaleFactor) {
this.scaleFactor = Math.max(min_zoom, Math.min(newScaleFactor, max_zoom));
if (targetView != null && originalWidth > 0) {
int newWidth = (int)(originalWidth * scaleFactor);
int newHeight = (int)(originalHeight * scaleFactor);
onScaleChanged(targetView, scaleFactor, newWidth, newHeight);
}
}
public void onScaleChanged(View targetView, float scaleFactor, int newWidth, int newHeight) {
ViewGroup.LayoutParams layoutParams = targetView.getLayoutParams();
layoutParams.width = newWidth;
layoutParams.height = newHeight;
// This is needed to increase the pane size (rather than zoom within the initial layout)
targetView.setLayoutParams(layoutParams);
// Tell the system to recalculate the layout
targetView.requestLayout();
// This is needed to specify the center of scaling
HorizontalScrollView horizontalScrollView = (HorizontalScrollView)targetView.getParent();
ScrollView vertScrollView = (ScrollView)horizontalScrollView.getParent();
// ~~~ the pivot points are probably wrong
targetView.setPivotX(horizontalScrollView.getScrollX() * scaleFactor);
targetView.setPivotY(vertScrollView.getScrollY() * scaleFactor);
// This is needed for actual zooming
targetView.setScaleX(scaleFactor);
targetView.setScaleY(scaleFactor);
};
public void zoomIn(float scaleDelta) {
changeScale(scaleFactor + scaleDelta);
}
public void zoomOut(float scaleDelta) {
changeScale(scaleFactor - scaleDelta);
}
Question 1: How do I prevent clipping? I can't find the right combination of scaleType and layout resizing.
Question 2: When I use setScaleX/setScaleY, should my pivot be calculated after applying the new scale factor or does the renderer take care of that automatically?
After updating the scale you need to invalidate(), and requestLayout() the views.
targetView.invalidate();
targetView.requestLayout();
I usually calculate the scale differently for images. You could try to scale the image view using the MATRIX scale type. You will need to know the size of your bound DPI.
// Get the scaled DPI
int boundBoxInDp = getResources().getDisplayMetrics().densityDpi * scaleFactor
// Determine how much to scale: the dimension requiring less scaling is
// closer to its side. This way the image always stays inside your
// bound AND either x/y axis touches the bound but neither will go over.
float xScale = ((float) boundBoxInDp) / newWidth;
float yScale = ((float) boundBoxInDp) / newHeight;
float scale = (xScale <= yScale) ? xScale : yScale;
// scale using our calculated scale
targetView.setScaleX(scale);
targetView.setScaleY(scale);
As to your second question about the Pivot. That will probably need to be set to the center of the visible scroll area. The the scrollable area should be increased when you change the image size since you are using FIT_CENTER;
See this article for code that works quite well. I ditched my HorizontalScrollView and ScrollView and attached this PanAndZoomListener to my FrameLayout and from then on it was all rainbows and unicorns.
I tried to do the same thing as you, but without success. It would seem that you can scroll an ImageView without using HorizontalScrollView and ScrollView. I'm still unclear as to what makes it happen, but I'm leaning toward the use of the image matrix (as in, setImageMatrix on ImageView) or possibly the use of MarginLayoutParams. In looking at the Gallery source code from the picture Gallery available on the Android, I'm seeing heavy use of Matrix. Unfortunately, the documentation on this seems to be quite light in my estimation.
Other people have figured it out, so plug in the PanAndZoomListener and you're done. That's what I did.
I currently have this xml:
<TextView android:id="#+id/dummy"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="#string/test"
android:textStyle="bold" />
And im trying to convert it to a java version so that I can set a typeface:
setContentView(R.layout.activity_main);
// the get the activity_main layout (getContentView method does not exist?)
FrameLayout layout = (FrameLayout) findViewById(android.R.id.content);
final TextView textView = new TextView(context);
textView.setId(R.id.dummy);
FrameLayout.LayoutParams contentLayout = new FrameLayout.LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT);
contentLayout.gravity = Gravity.CENTER;
textView.setText(R.string.test);
Typeface tf = Typeface.createFromAsset(getAssets(), "fonts/arial.ttf");
textView.setTypeface(tf);
layout.addView(textView, contentLayout);
The problem I'm having is that either does not gravity work or match_parent. The texts ends up in the upper right corner and not in the center as it does on the xml version.
In the XML you're setting the gravity of the text inside the TextView. In the code you are setting the TextView's layout gravity.
To replicate what you've done in the XML, change the line:
contentLayout.gravity = Gravity.CENTER;
to:
textView.setGravity(Gravity.CENTER);
If your XML had android:layout_gravity="center" instead of android:gravity="center" then your code would match as it is.
I have an app that needs to dynamically align text views over certain locations on an image. The image is scaled to fit the view. Text entries are added by the user. I'm using a RelativeLayout and margins to properly position the text. All is good.
When the user rotates the screen, I save the text locations and bitmap using onRetainNonConfigurationInstance(). When the view is recreated, I add the views back into the RelativeLayout. Now, because the view is a different size, the scale of the image is different. To keep the text boxes in the same location, I have to account for that. I have all that code working except for one issue....
If I create a TextView and set the fontSize to a small size (e.g. <11px), the top of the text box is positioned where I want it to be but the text is aligned with a baseline as if it were 11px font. I don't know the scale factor in the onCreate method so I can't change the font size until after onMeasure and onLayout are called. I've tried forceLayout() and requestLayout() but nothing seems to fix the alignment problem.
Here is the layout:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/scrollView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="0dp"
>
<com.xyx.ScalableLayout
android:id="#+id/layout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="0dp"
android:clickable="true"
android:gravity="top"
>
<com.xyx.ScaledImageView
android:id="#+id/formView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="0dp"
/>
<com.xyx.ScalableLayout>
</ScrollView>
A textView is added with the following code:
textView = new TextView(getContext());
textView.setPadding(0, 0, 0, 0);
textView.setSingleLine();
textView.setFocusableInTouchMode(false);
textView.setClickable(false);
textView.setGravity(Gravity.TOP);
textView.setText(entry.mText);
float fontSize = mImageView.mapSizeToView(entry.mPointSize);
textView.setTextSize(TypedValue.COMPLEX_UNIT_PT, fontSize);
params = new RelativeLayout.LayoutParams(
ViewGroup.MarginLayoutParams.WRAP_CONTENT,
ViewGroup.MarginLayoutParams.WRAP_CONTENT);
params.leftMargin = Math.round(viewLoc.x);
params.topMargin = Math.round(viewLoc.y);
addView(textView, params);
When ScaledImageView gets an onSizeChanged() callback, it sets the scale value and updates the font size and location of TextViews with the following code:
float fontSize = mImageView.mapSizeToView(entry.mPointSize);
textView.setTextSize(TypedValue.COMPLEX_UNIT_PT, fontSize);
PointF viewLoc = computeTopLeft(entry, entry.mTextView.getPaint());
params = (RelativeLayout.LayoutParams) textView.getLayoutParams();
params.leftMargin = Math.round(viewLoc.x);
params.topMargin = Math.round(viewLoc.y);
textView.setLayoutParams(params);
textView.forceLayout();
And finally, I do a
requestLayout() on the ScalableLayout
I know that's a lot of code but my problem is this. If I know the proper scale factor (used in mapSizeToView()) when I am creating the TextView and adding it to the screen everything works fine. If the value is incorrect, then nothing I can find will do a full recalculate that will get the TextView to be the same as if it were created with that font size. I believe it is tied to Android Layout structure which I generally understand. However, I don't understand why I can't get it to recompute from scratch (short of tearing down all the views and recreating them).