I want to scroll a content in a TextView, this is the code that sets the results to be displayed in a TextView:
do
{
y = m;
f = x / y;
m = (y + f) / 2;
str[i] = x + "\t " + y + "\t " + f + "\t " + m + "\t";
i++;
a = i;
} while (Math.abs(y - m) >= 0.00001 * y);
str4 = numfmt1.format(y);
for (int j = 0; j < a; j++){
ris.append(str[j] + "\n");//TextView that contains the string str
}
ris.append("La radice รจ: " + str4)
}
Place the TextView inside the ScrollView. But make careful as ScrollView can hold only one child.... and the TextView will be the child of the ScrollView. Do this using the xml or graphical layout functionality in eclipse.
<ScrollView>
TextView
</ScrollView>
Related
I have a for-loop code:
try
{
outputStream = new FileOutputStream("/sdcard/output1.txt");
Writer out = new OutputStreamWriter(outputStream);
Point point;
for (int i = 48; i <= 66; i++)
{
point = landmarks.get(i);
int pointX = (int) (point.x * resizeRatio);
int pointY = (int) (point.y * resizeRatio);
Log.d(TAG, "My points:(" + pointX + "," + pointY + ")");
point = landmarks.get(i + 1);
int pointXX = (int) (point.x * resizeRatio);
int pointYY = (int) (point.y * resizeRatio);
canvas.drawLine(pointX, pointY, pointXX, pointYY,mFaceLandmardkPaint);
out.write(Integer.toString(pointX));
String h = ",";
out.write(h);
out.write(Integer.toString(pointY));
String j = ",";
out.write(j);
}
out.write("\n");
out.close();
}
In this i need to start from 48 limit after the first 66 limit gets over.How can i again starts from 48th limit???
use recursion.
create a method to execute your forloop and at the end of loop call the method again.
like
if(i==65){
callMethodAgain();
}
and to break the loop store a temp variable to do the count ex.
if(i==65&& temp<2){
temp++;
callMethodAgain();
}
Try following code :
for(int j=0; j<2; j++){
for (int i = 48; i <= 66; i++)
{
if(j == 0){
point = landmarks.get(i);
int pointX = (int) (point.x * resizeRatio);
int pointY = (int) (point.y * resizeRatio);
Log.d(TAG, "My points:(" + pointX + "," + pointY + ")");
point = landmarks.get(i + 1);
int pointXX = (int) (point.x * resizeRatio);
int pointYY = (int) (point.y * resizeRatio);
canvas.drawLine(pointX, pointY, pointXX, pointYY,mFaceLandmardkPaint);
out.write(Integer.toString(pointX));
String h = ",";
out.write(h);
out.write(Integer.toString(pointY));
String j = ",";
out.write(j);
}
else{
// do your stuff
}
}
}
I have horizontal RecyclerView with images.
When i scroll it left, i have image order like this.
When i scroll it right, i have order like this.
I need to set central image on top, above left and right ones. How to do it?
I overrided getChildDrawingOrder method:
#Override
protected int getChildDrawingOrder(int childCount, int i) {
int centerChild;
//find center row
if ((childCount % 2) == 0) { //even childCount number
centerChild = childCount / 2; // if childCount 8 (actualy 0 - 7), then 4 and 4-1 = 3 is in centre.
int otherCenterChild = centerChild - 1;
//Which more in center?
View child = this.getChildAt(centerChild);
final int left = child.getLeft();
final int right = child.getRight();
//if this row goes through center then this
final int absParentCenterX = getLeft() + getWidth() / 2;
//Log.i("even", i + " from " + (childCount - 1) + ", while centerChild = " + centerChild);
if ((left < absParentCenterX) && (right > absParentCenterX)) {
//this child is in center line, so it is last
//centerChild is in center, no need to change
} else {
centerChild = otherCenterChild;
}
} else {//not even - done
centerChild = childCount / 2;
//Log.i("not even", i + " from " + (childCount - 1) + ", while centerChild = " + centerChild);
}
int rez;
//find drawIndex by centerChild
if (i > centerChild) {
//below center
rez = (childCount - 1) - i + centerChild;
} else if (i == centerChild) {
//center row
//draw it last
rez = childCount - 1;
} else {
//above center - draw as always
// i < centerChild
rez = i;
}
//Log.i("return", "" + rez);
return rez;
}
Also i set
setChildrenDrawingOrderEnabled(true);
Full code is here.
Fixed with adding ViewCompat.setTranslationZ(view, translationZ);
protected final void updateViews() {
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
//setMarginsForChild(child);
if (mAppearAnimationIsWorking)
child.setAlpha(0);
else
child.setAlpha(1);
if (mScaleUnfocusedViews && !mAppearAnimationIsWorking) {
float scale = computeScale(child);
child.setTranslationY(-getMeasuredHeight() * (1 - scaleFactor) / 2);
ViewCompat.setTranslationZ(child, -getPercentageFromCenter(child));
child.setScaleX(scale * scaleFactor * innerScale);
child.setScaleY(scale * scaleFactor * innerScale);
}
}
}
getChildDrawingOrder and setChildrenDrawingOrderEnabled can be removed.
So, for practice, i'm learning how to programatically create views. I've created a new layout extending Viewgroup (which I called Custom1) which puts children views (all of the same size) in two columns.
The children of this group are also a custom layout (which I called Custom2) containing an imageview, and two textviews. I use a for loop to add the necessary amount of views to the viewgroup, and the onLayout is overriden.
Now, I tried to run this on a Nexus 4 with the "show layout bounds" option checked. I can see the bounds of the children of the Custom1 are all in the right place, and based on the log, the children of custom2 are also in the correct place. However, only the first "custom2" is showing properly (I.e. the first custom2 shows an imageView and two textviews, the rest are empty).
Is it possible that the parent view is covering up the children views?
If not, has anybody run into a similar issue before?
Here is some of my code for custom1:
#Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
final int count = getChildCount();
if (ItemToDebug.equals("Layout")){
if (count == numberOfChannels){
Log.d("Layout:", "Number of children matches number of channels");
}else{
Log.d("Layout:", "Mismatch between number of children and number of channels");
}
Log.d("Layout:", "onLayout " + Integer.toString(count) + " children");
}
for (int i = 0; i < count; i++){
View child = getChildAt(i);
if (i%2 == 0){
if (LayoutLeftChild(i/2, l, t, r, b, child)){ //Lays out Child, returning a Boolean if successful
if (ItemToDebug.equals("Layout")){
Log.d("Layout:", "onLayoutLeftChild number " + Integer.toString(i/2) + "successful");
}
} else
if (ItemToDebug.equals("Layout")){
Log.d("Layout:", "onLayoutLeftChild number " + Integer.toString(i/2) + "failed");
}
}
if (i%2 == 1){
if (LayoutRightChild(i/2, l, t, r, b, child)){
if (ItemToDebug.equals("Layout")){
Log.d("Layout:", "onLayoutRightChild number " + Integer.toString(i/2) + "successful");
}
}else{
if (ItemToDebug.equals("Layout")){
Log.d("Layout:", "onLayoutRightChild number " + Integer.toString(i/2) + "failed");
}
}
}
}
}
/*
Left edge for right column = l + (r-l)/2 + 15
Right edge for right column = r - 20
20dp Margin between rows
Rows are 400 dp tall
*/
private boolean LayoutRightChild(int i, int l, int t, int r, int b, View child) {
final View Child = child;
final int Left = l + (r-l)/2 + 15;
final int Right = r - 20;
final int Top = t + i*20 + (i-1)*400;
final int Bottom = Top + 400;
Child.layout(Left, Top, Right, Bottom);
if (ItemToDebug.equals("Layout")){
Log.d("Layout:", "Child laid out at (" + Integer.toString(Left) + ", " + Integer.toString(Top) + ", " + Integer.toString(Right) + ", " + Integer.toString(Bottom) + ")");
}
return true;
}
/*
Left edge for left column = l + 20
Right edge for left column = l + (r-l)/2 - 15
20dp Margin between rows
Rows are 400 dp tall
*/
private boolean LayoutLeftChild(int i, int l, int t, int r, int b, View child) {
final View Child = child;
final int Left = l + 20;
final int Right = l + (r-l)/2 - 15;
final int Top = t + i*20 + (i-1)*400;
final int Bottom = Top + 400;
Child.layout(Left, Top, Right, Bottom);
if (ItemToDebug.equals("Layout")){
Log.d("Layout:", "Child laid out at (" + Integer.toString(Left) + ", " + Integer.toString(Top) + ", " + Integer.toString(Right) + ", " + Integer.toString(Bottom) + ")");
}
return true;
}
Here is some code from custom2:
#Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
final int count = getChildCount(); //There should be three children - one ImageView on top and two TextViews on bottom
if (ItemToDebug.equals("Layout")){
if (count == 3){
Log.d("View Contents:", "3 Children Views found");
}else{
Log.d("View Contents:", "Number of Children Incorrect. " + Integer.toString(count) + " children found.");
}
Log.d("Layout:", "onLayout " + Integer.toString(count) + " children");
}
//Get children here in for loop and place.
for (int i = 0; i < count; i++){
final View child = this.getChildAt(i);
//Layout should already have margins, so align contents with left and right sides.
int width = r - l;
int top;
int height;
switch(i){
case 0:
top = t;
height = 100;
if (ItemToDebug.equals("Layout")) {
Log.d("Layout:", "Image Laid out at (" + Integer.toString(l) + ", " + Integer.toString(top) + ", " + Integer.toString(r) + ", " + Integer.toString(top + height) + ")");
}
break;
case 1:
top = t + 100;
height = 60;
if (ItemToDebug.equals("Layout")) {
Log.d("Layout:", "TextView (nowPlaying) Laid out at (" + Integer.toString(l) + ", " + Integer.toString(top) + ", " + Integer.toString(r) + ", " + Integer.toString(top + height) + ")");
}
break;
case 2:
top = t + 160;
height = 60;
if (ItemToDebug.equals("Layout")) {
Log.d("Layout:", "TextView (nextPlaying) Laid Out at (" + Integer.toString(l) + ", " + Integer.toString(top) + ", " + Integer.toString(r) + ", " + Integer.toString(top + height) + ")");
}
break;
default:
top = t;
height = 0;
if (ItemToDebug.equals("Layout")){
Log.d("Layout:", "More than 3 children have been added to the Custom2");
}
break;
}
child.layout(l, top, r, top + height);
}
}
Here is my log:
https://drive.google.com/file/d/0B0EGM_1_9jazWEZ1RXh4a2VXdnM/view?usp=sharing
And the screenshot.
The answer can be found here: Views within a Custom ViewGroup are not showing
Children are laid our wrt their parents (left and top are 0)
I have a game board with 5x5 squares made of canvas drawrect:
protected void onDraw(Canvas canvas) {
for (int rowNo = 0; rowNo < nSquares; rowNo++) {
paint.setColor(((rowNo & 1) == 0) ? colorA : colorB);
for (int colNo = 0; colNo < nSquares; colNo++) {
int left = colNo * squareWidth;
int top = rowNo * squareWidth;
Rect areaRect = new Rect(left, top, left + squareWidth, top + squareWidth);
canvas.drawRect(areaRect, paint);
paint.setColor((paint.getColor() == colorA) ? colorB : colorA);
paint.setTextSize((float)(squareWidth*0.8));
RectF bounds = new RectF(areaRect);
String letter = "A";
bounds.right = paint.measureText(letter, 0, letter.length());
bounds.bottom = paint.descent() - paint.ascent();
bounds.left += (areaRect.width() - bounds.right) / 2.0f;
bounds.top += (areaRect.height() - bounds.bottom) / 2.0f;
canvas.drawText(letter, bounds.left, bounds.top - paint.ascent(), paint);
}
}
I want to track touch input to get the squares the user are touching..
My attempt was
public boolean onTouchEvent(MotionEvent event){
int action = MotionEventCompat.getActionMasked(event);
int x = (int)event.getX();
int y = (int)event.getY();
Log.i(DEBUG_TAG, "Position: (" + x + ", " + y + ")");
int squareTouched = gameBoard.getSquare(x,y);
}
where getSquare is
public int getSquare(int x, int y) {
int row = 0;
int col = 0;
for(int rowNo = 1; rowNo <= nSquares; rowNo++) {
Log.i("Row", "Width: " + squareWidth + " rowNo: " + rowNo + " rowNo*squareW: " + rowNo*squareWidth + " y: " + y);
if(rowNo*squareWidth > y)
{
row = rowNo;
break;
}
}
for (int colNo = 1; colNo <= nSquares; colNo++) {
if(colNo*squareWidth > x)
{
col = colNo;
break;
}
}
Log.i(DEBUG_TAG, "Row: " + row + " Col: " + col);
return (row-1)*nSquares + col;
}
The problem is that the onTouchEvent getX and getY are referring to the screen 0,0, but when I draw the squares 0,0,0,0 is referring to the view origin? Am I right?
How can I get the input position relative to the game board view?
Could it be a solution to get the view position in the screen and add/subtract this to the tochEvent x- and y position?
I assume that the onDraw() and getSquare() belong to GameBoardView and onTouchEvent() to its immediate parent. If so then the onTouchEvent() should be like this
public boolean onTouchEvent(MotionEvent event){
int action = MotionEventCompat.getActionMasked(event);
int x = (int)event.getX() - gameBoard.getX();
int y = (int)event.getY() - gameBoard.getY();
Log.i(DEBUG_TAG, "Position: (" + x + ", " + y + ")");
int squareTouched = gameBoard.getSquare(x, y);
}
In a View x and y in both onDraw() and onTouchEvent() is relative to the View itself (Except when the View is scrolled). Since in your case onTouchEvent() belongs to parent and onDraw() to child, I used View.getX() and getY() to translate the coordinates. View.getX() returns the x position plus translationX of the View relative to its parent.
I could not get the gameBoard().getX/Y() to return the correct values. My guess is that the action bar is excluded?
I now use getLocationOnScreen
#Override
public boolean onTouchEvent(MotionEvent event){
int action = MotionEventCompat.getActionMasked(event);
int boardLocation[] = new int[2];
gameBoard.getLocationOnScreen(boardLocation);
int touchX = (int)event.getX();
int touchY = (int)event.getY();
int x = touchX - boardLocation[0];
int y = touchY - boardLocation[1];
int squareTouched = gameBoard.getSquare(x,y);
}
Which solved my issue..
I set up an array[8] to store a string conversion. The X will range from 0 to 255. If X is less than 127 (7 bits) it does not write higher bit 0's. So I preset the array[8] to all 0's and the next routine would write only the changed data. Code compiles but the array[] all reads 1's regardless of what x= to.
int x = 10;
string=(Integer.toBinaryString(x));
int[] array = new int[8];
for (int j=0; j < 7; j++){
array[j]=0;
}
for (int i=0; i < string.length(); i++) {
array[i] = Integer.parseInt(string.substring(i,i+1));
}
Log.d("TAG", "Data " + array[0] + "" + array[1]+ "" + array[2] +
"" + array[3]+ "" + array[4]+ "" + array[5] +
"" + array[6] + "" + array[7]);
int x = 10;
String s=(Integer.toBinaryString(x));
int[] array = new int[8];
//no need for a loop that sets all values to 0.
int offset = array.length - s.length();
//you need this offset because the string may be shorter than the array
for (int i=0; i < s.length(); i++) {
array[i + offset] = Integer.parseInt(s.substring(i,i+1));
//applay the offset here
}
This will produce the follow array for int = 10:
[0, 0, 0, 0, 1, 0, 1, 0]