I'm trying to manually set the image-view position within my app, the code is currently working but all the facebook images display at the top right and side on top of each other.
I do not have access to any adaptors, this is within the Facebook SDK, can anyone spot any problems with the following code:
My XML:
DisplayPhotos.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/DisplayPhotosLayout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</RelativeLayout>
This is set by the following:
fbManager = new FBLoginManager(this, R.layout.displayphotos, "-------", permissions);
Then I use the following to display images (working but all in same position)
int Row = 0;
int RowCount = 0;
int imageWidth = (int)getWindowManager().getDefaultDisplay().getWidth() / 3;
for(int _i = 0; _i < _noOfPhotos; _i++)
{
ImageView imageView = new ImageView(getApplicationContext());
imageView.setImageResource(R.drawable.no_image);
RelativeLayout.LayoutParams rl = new RelativeLayout.LayoutParams(imageWidth, imageWidth);
rl.setMargins(imageWidth * _i, imageWidth * Row, 0,0);
RowCount = RowCount + 1;
if(RowCount == 3){Row = Row + 1;RowCount = 0;}
UrlImageViewHelper.setUrlDrawable(imageView, _userGallery.get(_i).getPicture());
addContentView(imageView, rl);
System.out.println(imageWidth * _i + " top: " + imageWidth * Row);
_imageViewArray.add(imageView);
}
I think you need a table layout, http://developer.android.com/guide/topics/ui/layout/grid.html
i've found a trick to place an imageview at absolute position xy inside a relative layout. the following code place the CENTER of a imageview at x,y, even outside the relativelayout boundaries.
/*
* relativelayout allow out-of-boudaries only along the alignment side.
* if aligned to left then you can have a negative x and overlap the
* left side, if aligned to right you can overlap the right
*
* let's put the image CENTERED on x,y
*
* If we are on the left side of the container
* | (x<dx/2) |<---imgDx-->|
* | |____________|
* |
* | x
* |<----------------> |
* |<----------> x-imgDx/2 |
* |____________________________________|
*
* if we goes past the half of the container
* <---imgDx--> |
* | |____________| |
* | x |
* |<---------------------> |
* | <----->| dx-(x+imgDx/2)
* |____________________________________|
*/
public void setBitmapPosition(ImageView iv, int x, int y) {
String log = "";
RelativeLayout rl = (RelativeLayout) iv.getParent();
// get bitmap size
int imgDx = iv.getLayoutParams().width;
int imgDy = iv.getLayoutParams().height;
// get container size
int dx = rl.getWidth();
int dy = rl.getHeight();
log = log + " XY:" + new Integer(x).toString() + ","
+ new Integer(y).toString();
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
imgDx, imgDy);
iv.setLayoutParams(lp);
log = log + " imgXY:" + new Integer(imgDx).toString() + ","
+ new Integer(imgDy).toString();
log = log + " winXY:" + new Integer(dx).toString() + ","
+ new Integer(dy).toString();
if (x <= (dx / 2)) {
// i'm on the left side of the view so let's align to left
lp.addRule(RelativeLayout.ALIGN_PARENT_LEFT,
RelativeLayout.TRUE);
lp.leftMargin = x - imgDx / 2;
log = log + " LEFT:" + new Integer(lp.leftMargin).toString();
} else {
// align to right. we are past the middle
lp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT,
RelativeLayout.TRUE);
lp.rightMargin = dx - (x + imgDx / 2);
log = log + " RIGHT:" + new Integer(lp.rightMargin).toString();
}
if (y <= (dy / 2)) {
// align to top
lp.addRule(RelativeLayout.ALIGN_PARENT_TOP, RelativeLayout.TRUE);
lp.topMargin = y - imgDy / 2;
log = log + " TOP:" + new Integer(lp.topMargin).toString();
} else {
// align to bottom
lp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM,
RelativeLayout.TRUE);
lp.bottomMargin = dy - (y + imgDy / 2);
log = log + " BOTTOM:"
+ new Integer(lp.bottomMargin).toString();
}
iv.setLayoutParams(lp);
Log.i("PARAM", log);
}
Related
I have tried to use the logic and pictorial representation from this SO. I am though confused with the images since one of them follow 4:1:1 whereas the later one does 4:2:2 nomenclature for YUV image (NV21).
Right now the issue is that i get an image (converted to Bitmap/PNG) with YUV component all over, essentially an unusable image.
Any recommendation to fix this?
private byte[] cropImage(byte[] data, Rect cropRect) {
int dataHeight = 480;
int dataWidth = 640;
int totalWH = dataWidth * dataHeight;
// make rect points even, currently the width & height is even number
// adjust x coordinates to make them
if (cropRect.left % 2 != 0 || cropRect.right % 2 != 0) {
cropRect.left -= 1;
cropRect.right -= 1;
}
// adjust y coordinates to make them even
if (cropRect.top % 2 != 0 || cropRect.bottom % 2 != 0) {
cropRect.top -= 1;
cropRect.bottom -= 1;
}
int area = cropRect.width() * cropRect.height() * 3/2;
Logger.getLogger().d("Size of byte array " + data.length + " Size of alloc area " + area);
byte[] pixels = new byte[area];//the size of the array is the dimensions of the sub-photo
// size.total = size.width * size.height;
// y = yuv[position.y * size.width + position.x];
// u = yuv[(position.y / 2) * (size.width / 2) + (position.x / 2) + size.total];
// v = yuv[(position.y / 2) * (size.width / 2) + (position.x / 2) + size.total + (size.total / 4)];
try {
// copy Y plane first
int srcOffset = cropRect.top * dataWidth;
int destOffset = 0;
int lengthToCopy = cropRect.width();
int y = 0;
for (; y < cropRect.height(); y++, srcOffset += dataWidth, destOffset += cropRect.width()) {
// Logger.getLogger().d("IO " + srcOffset + cropRect.left + " oO " + destOffset + " LTC " + lengthToCopy);
System.arraycopy(data, srcOffset + cropRect.left, pixels, destOffset, lengthToCopy);
}
Logger.getLogger().d("Completed Y copy");
// U and V components are not-interleaved, hence their size is just 1/4th the original size
// copy U plane
int nonYPlanerHeight = dataHeight / 4;
int nonYPlanerWidth = dataWidth / 4;
srcOffset = totalWH + (cropRect.top / 4 * nonYPlanerWidth);
for (y = 0; y < cropRect.height();
y++, srcOffset += nonYPlanerWidth, destOffset += cropRect.width() / 4) {
System.arraycopy(data, srcOffset + cropRect.left / 4, pixels, destOffset, cropRect.width() / 4);
}
Logger.getLogger().d("Completed U copy " + y + " destOffset=" + destOffset);
// copy V plane
srcOffset = totalWH + totalWH / 4 + (cropRect.top / 4 * nonYPlanerWidth);
for (y = 0; y < cropRect.height();
y++, srcOffset += nonYPlanerWidth, destOffset += cropRect.width() / 4) {
System.arraycopy(data, srcOffset + cropRect.left / 4, pixels, destOffset, cropRect.width() / 4);
}
Logger.getLogger().d("Completed V copy " + y + " destOffset=" + destOffset);
} catch (ArrayIndexOutOfBoundsException ae) {
// do nothing
Logger.getLogger().e("Exception " + ae.getLocalizedMessage());
}
return pixels;
}
This is a little bit complicated to explain, so apologies.
The basic requirement is annotator app on Android, which allows the user to draw over the desktop, take a snapshot and one or two other things.
When the app starts it shows a single icon. This can be moved about the desktop.
When this icon is single clicked (touch) 6 icons spread evenly centred around the central icon appear.
So far so good. Now we move the central icon, and re-calculate the positions of the 6 outer icons centred around the new position of the central icon.
What we find is the outer icons are off centre relative to the central icon. The displacement looks to be roughly equal (bot X and Y) by the position of the touch within the central icon.
I will attempt to draw what happens.
First when the touch point on the drag/move is in the centre, everything lines up perfectly:
When the touch point is to the right, the displacement is leftwards as below:
When the touch is at the bottom the displacement is upwards:
The position of the "x" relative to the icon is it seems from
int shiftX = event.getX();
int shiftY = event.getY();
The position of the moved icon is from :
view.getLocationInWindow(locWXY);
int X = locWXY[0];
int Y = locWXY[1];
So, the positions of the satellite icons are calculated as:
final double angle = 30.000;
final double rad = angle * Math.PI / 180.000;
final int radius = 100;
final int penX = (int) (X + radius * cos(rad) + shiftX);
final int penY = (int) (Y - radius * sin(rad) + shiftY);
final int clearX = X ;
final int clearY = (int) (Y - radius + shiftY);
final int closeX = (int) (X - radius * cos(rad) + shiftX);
final int closeY = (int) (Y - radius * sin(rad) + shiftY);
final int iFlipX = (int) (X - radius * cos(rad) + shiftX);
final int iFlipY = (int) (Y + radius * sin(rad) + shiftY);
final int sshotX = X + shiftX;
final int sshotY = (int) (Y + radius + shiftY);
final int iFolderX = (int) (X + radius * cos(rad) + shiftX);
final int iFolderY = (int) (Y + radius * sin(rad) + shiftY);
penLP= new RelativeLayout.LayoutParams(70, 70);
penLP.leftMargin = penX;
penLP.topMargin = penY;
imbBlackPen.setLayoutParams(penLP);
clearLP = new RelativeLayout.LayoutParams(70, 70);
clearLP .leftMargin = clearX;
clearLP .topMargin = clearY;
imbClearScreen.setLayoutParams(clearLP );
folderLP = new RelativeLayout.LayoutParams(70, 70);
folderLP .leftMargin = iFolderX ;
folderLP .topMargin = iFolderY;
imbFolder.setLayoutParams(folderLP );
sshotLP = new RelativeLayout.LayoutParams(70, 70);
sshotLP .leftMargin = sshotX ;
sshotLP .topMargin = sshotY;
imbScreenCapture.setLayoutParams(sshotLP );
iFlipLP = new RelativeLayout.LayoutParams(70, 70);
iFlipLP .leftMargin = iFlipX ;
iFlipLP .topMargin = iFlipY;
imbIflipChart.setLayoutParams(iFlipLP );
closeLP = new RelativeLayout.LayoutParams(70, 70);
closeLP .leftMargin = closeX ;
closeLP .topMargin = closeY;
imbClose.setLayoutParams(closeLP );
I have tried setting shiftX and shiftY to zero, calculating X and X + shiftX/2. All to no avail. The strange thing is that on a small 10 inch tablet with resolution 1920 x 1200 it looks almost perfect, but on a large 65 inch touch screen the displacement is extremely pronounced.
We must be missing something, but I cannot figure out what.
As commented above ...
Fixed. The icon position calculation code above needed to be executed on ACTION_UP as well as ACTION_DOWN. Refactored this as a method and called it on both these events.
I am using GraphView Library for creating Bar graph as shown in picture, I need to reduce width of bars and increase space between bars.
Note- Red bars are currently what I'm getting and what I actually need is shown in black.
Below is the code snippet for the above graph:
GraphViewSeriesStyle barStyle = new GraphViewSeriesStyle();
barStyle.thickness = 5;
barStyle.setValueDependentColor(new ValueDependentColor() {
#Override
public int get(GraphViewDataInterface data) {
return Color.rgb(205, 0, 0);
}
});
// init example series data
GraphViewSeries scoreSeries = new GraphViewSeries(
"HealthCare Bar Graph", barStyle, new GraphViewData[] {
new GraphViewData(1, rsCVD),
new GraphViewData(2, rsHypertension4),
new GraphViewData(3, rsHypertension2),
new GraphViewData(4, rsHypertension1) });
GraphView graphView = new BarGraphView(this // context
, "GRAPH_VIEW_HEADING" // heading
);
graphView.setHorizontalLabels(new String[] { "1", "2",
"3", "4" });
graphView.addSeries(scoreSeries);
graphView.setViewPort(0, 25);
graphView.setScalable(true);
graphView.getGraphViewStyle().setHorizontalLabelsColor(Color.BLACK);
graphView.getGraphViewStyle().setVerticalLabelsColor(Color.BLACK);
graphView.getGraphViewStyle().setTextSize(16);
graphView.getGraphViewStyle().setGridColor(Color.WHITE);
// graphView.getGraphViewStyle().setLegendWidth(legendWidth)
int maxValue = myScore+1;
// search the interval between 2 vertical labels
double interval;
if (maxValue >= 0 && maxValue < 3) {
interval = 0.5; // increment of 1 between each label
} else if (maxValue >= 3 && maxValue < 55) {
interval = 5; // increment of 5 between each label
} else if (maxValue >= 55 && maxValue <= 110) {
interval = 10; // increment of 10 between each label
} else {
interval = 20; // increment of 20 between each label
}
// search the top value of our graph
int maxLabel = maxValue;
while (maxLabel % interval != 0) {
maxLabel++;
}
// set manual bounds
graphView.setManualYAxisBounds(maxLabel, 0);
// indicate number of vertical labels
int numVerticalLabels = (int) ((int) maxLabel / interval + 1);
Log.v(TAG, "numVerticalLabels: " + numVerticalLabels);
graphView.getGraphViewStyle().setNumVerticalLabels(numVerticalLabels);
graphView.getGraphViewStyle().setVerticalLabelsWidth(20);
// graphView.getGraphViewStyle().setLegendWidth(20);
graphView.getGraphViewStyle().setLegendSpacing(30);
// LinearLayout layout = (LinearLayout) findViewById(R.id.layout);
m_llayForRiskGraphContainer.addView(graphView);
there's currently no build in method to do this. but if you want to, you can easily modify the code. The point where you can add a spacing is here:
BarGraphView.java Line 95:
float left = (i * colwidth) + horstart -offset;
float top = (border - y) + graphheight;
float right = ((i * colwidth) + horstart) + (colwidth - 1) -offset;
canvas.drawRect(left, top, right, graphheight + border - 1, paint);
Just add a few pixels to left and remove a few pixels from right and it will look like you want.
https://github.com/jjoe64/GraphView/blob/master/src/main/java/com/jjoe64/graphview/BarGraphView.java#L97
Can anybody tell me how to change data dynamically in onLayout().i want to display first 8 values and after rotation complete another 8 values until it display array limit.here is my code-
if (position < conversion.length) {
if (!childRotate) {
child.setAngle(angle);
child.setPosition(i);
position = i;
child.setImageResource(conversion[position]);
Float an = angle;
Log.i("prj,=angle", an.toString() + ",i=" + i.toString()
+ ",onlayout,position=" + position.toString());
position++;
} else {
child.setAngle(angle);
child.setPosition(i);
child.setImageResource(conversion[position]);
Float an = angle;
Log.i("prj,angle=", an.toString() + ",i=" + i.toString()
+ ",onlayout,position=" + position.toString());
position++;
// childRotate = false;
}
}
left = Math
.round((float) (((layoutWidth / 2) - childWidth / 2) + radius
* Math.cos(Math.toRadians(angle))));
top = Math
.round((float) (((layoutHeight / 2) - childHeight / 2) + radius
* Math.sin(Math.toRadians(angle))));
child.layout(left, top, left + childWidth, top + childHeight);
angle += angleDelay;
I got these piece of codes or patches from osmdroid, and I decided to ask for your help guys because i don't have the enough knowledge to combine these codes to come up with on a solution on my problem, Scrolling limit on an offline map. I searched across the web, and modified tutorials. Honestly I tried to modify these codes but i have not found any progress. Basically I have an offline map from mapnik, and a few overlays. I don't know where to properly place these set of codes. Your ideas and modification will be a great help and also helps me keep going with my project and I guess your answers will definitely help others with the same problem as mine in the future. I know this is to much. Thank you sirs for your time, and God Bless.
public void onCreate(Bundle savedInstanceState) {
...
...
m_mapView = (MapView) findViewById(R.id.mapview);
m_mapView.setTileSource(TileSourceFactory.MAPNIK);
}
First: BoundingBox
BoundingBoxE6 bbox = new BoundingBoxE6(9.37398, 123.33761, 9.23948, 123.25035);
this.setScrollableAreaLimit(bbox);
Second: LimitScrollToGeographicArea.patch
Index: MapView.java
===================================================================
--- MapView.java (revision 944)
+++ MapView.java (working copy)
## -103,6 +103,8 ##
protected MapListener mListener;
+ protected Rect mScrollableAreaLimit;
+
// for speed (avoiding allocations)
private final Matrix mMatrix = new Matrix();
private final MapTileProviderBase mTileProvider;
## -505,6 +507,36 ##
mMapOverlay.setUseDataConnection(aMode);
}
+ /**
+ * Set the map to limit it's scrollable view to the specified BoundingBoxE6. Note that, like
+ * North/South bounds limiting, this allows an overscroll of half the screen size. This means
+ * each border can be scrolled to the center of the screen.
+ *
+ * #param boundingBox
+ * A lat/long bounding box to limit scrolling to, or null to remove any scrolling
+ * limitations
+ */
+ public void setScrollableAreaLimit(BoundingBoxE6 boundingBox) {
+ final int worldSize_2 = TileSystem.MapSize(MapViewConstants.MAXIMUM_ZOOMLEVEL) / 2;
+
+ // Clear scrollable area limit if null passed.
+ if (boundingBox == null) {
+ mScrollableAreaLimit = null;
+ return;
+ }
+
+ // Get NW/upper-left
+ final Point upperLeft = TileSystem.LatLongToPixelXY(boundingBox.getLatNorthE6() / 1E6,
+ boundingBox.getLonWestE6() / 1E6, MapViewConstants.MAXIMUM_ZOOMLEVEL, null);
+ upperLeft.offset(-worldSize_2, -worldSize_2);
+
+ // Get SE/lower-right
+ final Point lowerRight = TileSystem.LatLongToPixelXY(boundingBox.getLatSouthE6() / 1E6,
+ boundingBox.getLonEastE6() / 1E6, MapViewConstants.MAXIMUM_ZOOMLEVEL, null);
+ lowerRight.offset(-worldSize_2, -worldSize_2);
+ mScrollableAreaLimit = new Rect(upperLeft.x, upperLeft.y, lowerRight.x, lowerRight.y);
+ }
+
// ===========================================================
// Methods from SuperClass/Interfaces
// ===========================================================
## -772,10 +804,26 ##
//I am confused with these codes below, where should I declare it? Int x, y in the onCreate method?
x += (worldSize_2 * 2);
while (x > worldSize_2)
x -= (worldSize_2 * 2);
- while (y < -worldSize_2)
- y += (worldSize_2 * 2);
- while (y > worldSize_2)
- y -= (worldSize_2 * 2);
+ if (y < -worldSize_2)
+ y = -worldSize_2;
+ if (y > worldSize_2)
+ y = worldSize_2;
+
+ if (mScrollableAreaLimit != null) {
+ final int zoomDiff = MapViewConstants.MAXIMUM_ZOOMLEVEL - getZoomLevel();
+ final int minX = mScrollableAreaLimit.left >> zoomDiff;
+ final int minY = mScrollableAreaLimit.top >> zoomDiff;
+ final int maxX = mScrollableAreaLimit.right >> zoomDiff;
+ final int maxY = mScrollableAreaLimit.bottom >> zoomDiff;
+ if (x < minX)
+ x = minX;
+ else if (x > maxX)
+ x = maxX;
+ if (y < minY)
+ y = minY;
+ else if (y > maxY)
+ y = maxY;
+ }
super.scrollTo(x, y);
// do callback on listener
Another one:
scrollToMethod
public void scrollTo(int x, int y) {
int curZoomLevel = mZoomLevel;
final int worldSize_2 = TileSystem.MapSize(curZoomLevel) / 2;
Log.v("HELP", "Scrolling to X=" + x + " Y=" + y + " ZL=" + curZoomLevel + " - WW="+worldSize_2);
while (x < -worldSize_2)
x += (worldSize_2 * 2);
while (x > worldSize_2)
x -= (worldSize_2 * 2);
if (y < -worldSize_2)
y = -worldSize_2;
if (y > worldSize_2)
y = worldSize_2;
if (mScrollableAreaLimit != null) {
int targetZoomLevel = getZoomLevel();
final int zoomDiff = MapViewConstants.MAXIMUM_ZOOMLEVEL - targetZoomLevel;
//final int zoomDiff = MapViewConstants.MAXIMUM_ZOOMLEVEL - mZoomLevel;
final int minX = mScrollableAreaLimit.left >> zoomDiff;
final int minY = mScrollableAreaLimit.top >> zoomDiff;
final int maxX = mScrollableAreaLimit.right >> zoomDiff;
final int maxY = mScrollableAreaLimit.bottom >> zoomDiff;
Log.v("HELP", "Limit: minX=" + minX + " maxX=" + maxX + " minY=" + minY + " maxY=" + maxY + " ZL=" + curZoomLevel + " ZLTarget="+ targetZoomLevel + " ZD="+zoomDiff);
if (x < minX) {
Log.v("HELP", "!!! X=" + x + " minX=" + minX + " CORRECTION:" + (minX-x));
x = minX;
} else if (x > maxX) {
Log.v("HELP", "!!! X=" + x + " maxX=" + maxX + " CORRECTION:" + (maxX-x));
x = maxX;
}
if (y < minY) {
Log.v("HELP", "!!! Y=" + y + " minY=" + minY + " CORRECTION:" + (minY-y));
y = minY;
} else if (y > maxY) {
Log.v("HELP", "!!! Y=" + y + " maxY=" + maxY + " CORRECTION:" + (maxY-y));
y = maxY;
}
}
super.scrollTo(x, y);
// do callback on listener
if (mListener != null) {
final ScrollEvent event = new ScrollEvent(this, x, y);
mListener.onScroll(event);
}
}
First of all use this command on your terminal:
svn checkout http://osmdroid.googlecode.com/svn/branches/release_3_0_5
It will download a stable version
Then follow this to import contents of the folder you downloaded:
In Eclipse, right-click on the Package area, and select the following:
click on Import...
select General -> Existing Projects into Workspace
click Next
click Browse...
select the checked out projects' directories
osmdroid-android (import as a java project)
OSMMapTilePackager (import as a java project)
OpenStreetMapViewer (mport as an android project)
click OK
click Finish
Now open this java file-->
osmdroid-android/src/org/osmdroid/view/MapView.java
Now as stated in this patch file, modify MapView.java ( add
code wherever + , remove code wherever -)
Also modify computeScroll() in MapView.java as stated here
Now, to use this modified .java file, you need to create a new jar
file that you can include in your project
Here is a step by step process to create jar
Add this newly created jar file to your project's build path and you
are ready to use your modified jar
Now use this in your activity class:
BoundingBoxE6 bbox = new BoundingBoxE6(limit north, limit east, limit south, limit west);
mapView.setScrollableAreaLimit(bbox);