I have a relative layout with textviews ordered in more then one column. When clicked on screen, there is a "popup screen" or "input screen" (have no idea how it is called) in which I define the time "from" and "to", what is the name of school class etc. It will compute which textviews it needs to merge from that input. Merged textviews have to be like one larger textview. Is it possible to do something like this?
Thanks for the answer in ahead.
Something like this:
http://i.stack.imgur.com/r1o8D.png
I've got an idea you could try creating a custom view to draw this instead of using views.
Extend the View class in a new class and override the onDraw method.
//variables
Paint paint[]; //Set up these paints with the colors you need
int rowWidth, int colHeight;
void onDraw(Canvas c){
for(int i=0;i<noOfRows;i++){
for(int j=0;j<noOfColumns;j++){
if(cellRequired(i,j)){
//cellRequired will be whatever logic you have to check if cell is required
int rectHeight=colHeight; //Now the Rect Height changes whether the cell
// below is in use or not.
for(int k=i;k<noOfRows;k++){
//This loop will run through the rows and see if merging is required
if(cellRequired(i,k))
rectHeight+=colHeight; //Merge Cell
else
break; //If not required at any point break loop
}
//Draw Rectangle background
c.drawRect(i*rowWidth +i, j*colHeight +j, rowWidth, rectHeight, backPaint);
//Draw Text
canvas.drawText("Text",i*rowWidth +i, j*colHeight +j, paint[requiredPaint]);
//I added the plus i and plus j so there'd be a gap in the rectangles
// Then it will be a border
}
}
}
}
Android documentation on custom controls
you
Android: Tutorial on Custom View creation
How to make a custom view similar to above
http://www.droidnova.com/playing-with-graphics-in-android-part-i,147.html
Go through these and then through the code above. Hopefully it should show you how to implement it.
Related
I dynamically add textviews to a relative layout based on user response to create a coloured grid pattern. Typically this can contain 5000+ textviews which have different background colors based on the value in textview tag.
I have this method where I iterate through all the textviews to show only those that have the same color and set the rest to gray. This works well when there are say 500 textviews but when the number is higher, say 5000 it take 13 seconds to complete.
if (code.equals("all")) {
for (int i = 0; i < textViewIDs.size(); i++) {
TextView tv = (TextView) findViewById(textViewIDs.get(i));
if (!tv.getTag().toString().equals("header")) {
tv.setBackgroundColor(Color.parseColor("#" + tv.getTag().toString()));
}
}
} else {
for (int i = 0; i < textViewIDs.size(); i++) {
TextView tv = (TextView) findViewById(textViewIDs.get(i));
if (!tv.getTag().equals(code)) {
if (!tv.getTag().toString().equals("header")) {
tv.setBackgroundColor(Color.LTGRAY);
}
}else{
tv.setBackgroundColor(Color.parseColor("#" + tv.getTag().toString()));
}
}
}
textViewIDs is the array holding all the textview ids.
What if anything can be done to speed this up?
Update:
I understand that having that number of widgets is not ideal however I could not come up with a better solution.
As well as each grid cells, in this case each texview, having different colors I also need to be able to manage onclick event for the cell so that I can add text. That was the reasoning for the textviews. Prior to using textviews I drew all the elements but that's when I couldn't find a way to add onclick event to each cell.
I'd better detail the concept to help you guys with what I'm trying to achieve and if I've gone down the wrong road.
This is part of a much larger app where I'm converting images into stitch charts.
Based on user input a grid of colored cells is drawn where each cell is a solid color that has been calculated from the original image most dominant color.
The grid will be larger than the screen so my views are placed in both horizontal and scroll views so they can be panned and zoomed. (This is all working well).
The grid cells have to click-able so I can turn on or off the background colors and also add a single text "X" character to mark stitch (cell) as completed.(This is to slow when the number of textview (cells) are > 500)
Hope there is enough detail there...
findViewById() seems to be your pressure point.
Instead of keeping a list of the ids, I'd a keep a list of references to the Views themselves (WeakReferences if leaks are a possibility)!
1 - for (int i = 0; i < textViewIDs.size(); i++) { ...
It's not optimized: precalculate your limit in a variable before starting the cycle:
int len = textViewIDs.size(); and use len in your cycle.
2 - i-- (I call it "reverse loop") seems to be faster than i++. See a nice loop comparison here
It's a bad practice to have that many TextView's, low-end devices will not be able to load it.
Try making one TextView with multiple styles in it, you can use HTML tags for background colors.
Or even better is to create just one ListView, this will recycle the views for you.
Hi I'm trying to add an activity that displays 4 images (imagine a square cut to quarters) where each image shows a different one when clicked, I have tried a few layouts using image buttons to no avail but then read here my answer is a grid view using image pager but when implementing this I get small images spaced quite far apart in grid view is there a better way please?
if it's always 2x2 images you can simply use a vertical linear layout and two horizontal layouts in it and then put your images as ImageButton or ImageView inside the horizontal layouts...
if it needs to be dynamic a gridlayout would probably be a good idea...
however, you need to provide more detailed information on what the issue is, if you need a more detailed answer...
(edit: I meant gridview, gridlayout is only available since api level 14)
You can use a RelativeLayout in order to add your ImageButtons and have all the control to your hands for location of buttons, size etc.
A different point of view, is to break your screen into 4 Rectangles (Rects).
Something like this :
Rect upLeftRect = new Rect(0,0,screenWidth/2 , screenHeight/2);
Rect upRightRect = new Rect(screenWidth/2,0,screenWidth,screenHeight/2);
Rect downLeftRect = new Rect(0,screenHeight/2, screenWidth/2 , screenHeight);
Rect downRightRect = new Rect(screenWidth/2, screenHeight/2, screenWidth,screenHeight);
The, attach an onTouchListener on your relativeLayout, something like this in your constructor:
yourRelativeLayout.setOnTouchListener(this);
And finally , inside the onTouch method you will have something like this :
#Override
public boolean onTouch(View v, MotionEvent e){
if(upLeftRect.contains( ( int ) e.getX(), (int) e.getY){
// do whatever you want, i guess that you want some alpha animation or something like this
}else if(upRightRect.contains( (int) e.getX(), (int) e.getY(){
// bla bla.. :)
} // do the rest conditions your self!!
Hope that helped!
I'm trying to make my own custom view, currently all it does is draw an image on a specific x and y coordinate and then draws the similar images repeatedly on different locations.
I want to be able to create a button on each instance of the image that is drawn. if one image is clicked it will have cause something different to happen depending on which image is chosen.
How can I implement this?
would I have to create a different view for each image/button combination and then set an onClick event?
Let me try to be a little more clear
I'm trying to make a map using hexagon (different types of terrains for different players)
I've figured out how to get them to draw (see here - they will have a border to show what terrain is owned by whom)
I just made a custom view class and had the hexagons drawn using a Canvas; however, I'm not sure how to be able to make the hexagons into buttons so that I can differentiate between which hexagon was chosen and how it should react to the opponents spot.
I was thinking of making a ViewGroup called Terrain to contain the Nodes(hexagons) that belong to the player and have a group of Node Views that only draw the hexagon where it should be located.
the question is can i make each node or the entire viewGroup into a button (or do an onTouch ) if a certain hexagon is pressed?
If I understood well, you should do :
One template my_pictures.xml which is a simple button.
Then you create a custom adapter which as a function for each kind of image you wanna create. By this, I mean that you will have to change the background value of your button depending on what you need it to be. Then you do a notifyDataSetChanged(); to refresh the container with the new button.
For the Listener, you just have to add it either in your activity or your adapter when you create your buttonImages, I don't know what's better.
Thanks for your help!
I figured out what I needed to do.
I have a NodeView class and in my GameActivity class, I'm using a relative layout and setting the layout parameters of where I wanted things positioned
RelativeLayout rl = new RelativeLayout(this);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(95,95);
params.leftMargin = 10;
params.topMargin = 10;
params = new RelativeLayout.LayoutParams(95,95);
params.leftMargin = 10+95*x;
params.topMargin = 81+(71*y);
rl.addView(new NodeView (this,0,0,1,1), params);
This helped me add things where I needed them and now all I'm trying to figure out how to scroll around the territories on both the x and y axis (I tried ScrollView but that only allows me to scroll on the y-axis, I'm looking into it though)
I am drawing a custom view in my application which basically takes arguments(XML) as the text to display and then keeps on rotating it infinitely.
While I was making this control I had a few doubts which I want to ask:
I have made 2 of my stylable attributes which I have declared in the attrs.xml file. These attributes are to set the width and the width of the circle used in my control. These values I would use in the ondraw method and the onmeasure method. I ran my program by declaring just these but there was an error which asked me to put android:width and android:height attributes. My question is why would I need those if I am already using my custom attributes to define the height and the width of my view
I am coding on a mac. Now when I was making my attrs.xml file, to get the autocomplete list which we usually get by ctrl+space was not showing up. Why is that. For e.g., i wanted to know what values can I give the format attribute of my custom attribute that like I am demostrating in the following:
<attr name ="somename" format="value I wanted to find out through autocomplete"> . Why is the autocomplete not popping up? It does pop up when I am making a.java file.
In my ondraw() method I wanted to draw a circle. Now for this I would require the co-ordinates of the center of the circle. So what I do is put 0, 0. But this is not correct. I want the circle to be at the center of the parent view it is in. So if my view is in a hierarchy I want it to respect that. I want to give the co-ordinates relative to the parent view. What is happeining right now is that it is being drawn at the top left corner of my screen. This is what I don't want. What do I do to achieve this?
why would I need those if I am already using my custom attributes to define the height and the width of my view?
This is because Android needs to know how and where to put your view in the layout. You can implement your view to make use of your custom height/width requirements by overriding View.onMeasure() to return your own size parameters. You can then just set android:layout_width="wrap_content" android:layout_height="wrap_content" in your layout file.
Why is the autocomplete not popping up? It does pop up when I am making a.java file.
Autocomplete and autodoc implementation for Android xml files is shaky at best, so it's not really surprising that it doesn't work. I'm not aware of a fix and AFAIK it's an IDE bug.
In my ondraw() method I wanted to draw
a circle. Now for this I would require
the co-ordinates of the center of the
circle. So what I do is put 0, 0. But
this is not correct. I want the circle
to be at the center of the parent view
it is in. So if my view is in a
hierarchy I want it to respect that. I
want to give the co-ordinates relative
to the parent view. What is happeining
right now is that it is being drawn at
the top left corner of my screen. This
is what I don't want. What do I do to
achieve this?
If you implemented onMeasure() correctly, the coordinates relative to parent should be taken care of already. To get the center of your view use the following code:
void onDraw(Canvas canvas)
{
int centerX = this.getWidth() / 2;
int centerY = this.getHeight()) / 2;
//..draw code here
}
Edit
Here's an example with source code that should help: http://mindtherobot.com/blog/272/android-custom-ui-making-a-vintage-thermometer/
I have a long text so I've decided to divide it into pages, and I put a so each swipe scrolls to the next page.. The way I did it was:
NumberOfPages=text.length()/CharPerPage; //CharPerPage=500;
NumberOfPages++;
Chapters.add(text.indexOf(" ", CurrentPage*CharPerPage));
CurrentPage++;
int tmp=0;
for(int i =NumberOfPages;i>0;i--)
{
tmp =(CurrentPage*CharPerPage);
if(tmp>text.length())
{
Chapters.add(text.length());
break;
}
else
{
Chapters.add(text.indexOf(" ", tmp));
CurrentPage++;
}
}
So I divide the text into pages, and each page has 500 chars... But this isnt good since Android has different screen sizes and shapes, and line breaks arent counted so it may go beyond the screen...
So can anyone suggest a way to know how many chars are needed to fill the screen so i can make the rest of the text to another page? Thanks.
Ok here is a shot - and a rather clumsy one but in short:
*You need need to know if any give line of text will fit width-wise in your view
*You need to know how many lines you have
*You need to handle embedded newlines
so
will some text fit on any given line
private boolean isTooLarge (TextView text, String newText) {
float textWidth = text.getPaint().measureText(newText);
return (textWidth >= text.getMeasuredWidth ());
}
how many lines does your textview have:
numLinesPerPage=mTextView.getHeight()/mTextView.getLineHeight(); //not this doesn't handle special cases where you've changed the font, bolded it etc
With these two tools you could iterate through your text adding words keeping track of how many lines you have left to work with (and handle your newlines if your text contains them)
note: getHeight can't be called in constructor since it doesn't know the height yet - you could also do this in onDraw or maybe onMeasure if you have a custom control.