Programmatic ImageView android duplicate rows - android

So I have a function for an android app that is supposed to take any number of pictures and display them 5 pics for each row, for some reason when it goes to the second row, it just repeats the pics for the first row, for example if I have 7 pics numbered 1-7 they will display:
12345
12
here is my function, thanks for any advice.
public void generateImageView(int number, String path){
//ImageView[] imageViewArray = new ImageView[number];
int ROW_ITEMS = 5; // 5 images per row
RelativeLayout rl = (RelativeLayout) findViewById(R.id.RelativeLayout1);
int limit = number;//limits the number of created imageViews to number
int rows = limit / ROW_ITEMS;//number of rows
int leftOver = limit % ROW_ITEMS; //see if we have incomplete rows
if (leftOver != 0){
rows += 1;
}
int id = 1000;
int belowId = R.id.send;
while (rows > 0){
int realItemsPerRow = ROW_ITEMS;
if (leftOver != 0 & rows == 1){
realItemsPerRow = Math.min(ROW_ITEMS, leftOver);
}
for (int i = 0; i < realItemsPerRow; i++){
Bitmap myBitmap = BitmapFactory.decodeFile(path + i + ".png");
ImageView imageViewArray = new ImageView(MainActivity.this);
imageViewArray.setId(id);
imageViewArray.setImageBitmap(myBitmap);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
imageViewArray.setPadding(10,10,0,0);
imageViewArray.setAdjustViewBounds(true);
imageViewArray.setMaxHeight(80);
imageViewArray.setMaxWidth(80);
if (i==0) {
lp.addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE);
} else {
lp.addRule(RelativeLayout.RIGHT_OF, imageViewArray.getId() -1);
}
lp.addRule(RelativeLayout.BELOW, belowId);
imageViewArray.setLayoutParams(lp);
rl.addView(imageViewArray);
id++;
}
belowId = id - 1;
rows--;

It's because you're just pulling the same images for each position in the row:
Bitmap myBitmap = BitmapFactory.decodeFile(path + i + ".png");
Before while( rows > 0 ) add:
int j = 0;
Then change the above to:
Bitmap myBitmap = BitmapFactory.decodeFile(path + ( j * ROW_ITEMS + i ) + ".png");
and under rows--; add:
j++;

Related

Android : How to add IDs Views to R.java dynamically with String resources?

I've created some buttons dynamically, when i start activity all is well, but when i rotate a screen or press back Button, i lose all buttons, i've googled then i've found that the views without IDs can't be saved, so i want to set IDs for them dynamically and i want to find them inside R.java file with there name like this :
public static final class id {
public static final int Button1=0x7f070027;
public static final int Button2=0x7f070024;
}
I've tried setId() but the problem is not solved, and i think it's not the same thing when use setID(); and set id manually inside String file, so i need your help thanks in advance(^_^).
here's my source code :
TableLayout TL = (TableLayout) findViewById(R.id.tlRDV);
TL.removeAllViews();
j = 0;
for (int i = 0; i < nbH; i++) {
TableRow tr = new TableRow(this);
tr.setLayoutParams(new LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
tr.setId(View.generateViewId());
TextView text_view = new TextView(this);
Button b = new Button(this);
text_view.setWidth(1000);
j = j + averageConsultationTime;
HMA = ((BeganConsultationH * 60) + (BeganConsultationM))
+ j - averageConsultationTime;
int h = HMA / 60;
int m = HMA % 60;
b.setBackgroundColor(0xff99cc00);
b.setText(h + "H" + m);
tr.addView(b);
for (int k = 0; k < 7; k++) {
Button but = new Button(this);
but.getId(View.generateViewId());
but.setText("" + but.getId());
but.setOnClickListener(getOnClickDoSomething(but,
jours[k] + "_" + h + "H" + m));
tr.addView(but);
}
TL.addView(tr);
}
}
}
}

Dynamically adding a button to RelativeLayout not working correctly

My goal is to add a number of buttons (in a 4 column grid) to a RelativeLayout depending on how many "items" are in the database. When I was first learning how to add buttons to a RelativeLayout I just created 6 static buttons and added them the following way (ItemButton is simple class that extends Button):
private void loadItemButtons2(){
itemButtonLayout = (RelativeLayout)findViewById(R.id.itemButtonLayout);
itemButtonLayout.removeAllViews();
ArrayList<Item> items = db.getAllActiveItems();
ItemButton b1, b2, b3, b4, b5, b6;
b1 = new ItemButton(this, items.get(0));
b2 = new ItemButton(this, items.get(1));
b3 = new ItemButton(this, items.get(2));
b4 = new ItemButton(this, items.get(3));
b5 = new ItemButton(this, items.get(4));
b6 = new ItemButton(this, items.get(5));
RelativeLayout.LayoutParams params1 = (RelativeLayout.LayoutParams)b1.getLayoutParams();
params1.addRule(RelativeLayout.ALIGN_PARENT_START);
b1.setId(111);
b1.setLayoutParams(params1);
RelativeLayout.LayoutParams params2 = (RelativeLayout.LayoutParams)b2.getLayoutParams();
params2.addRule(RelativeLayout.RIGHT_OF, 111);
b2.setId(222);
b2.setLayoutParams(params2);
RelativeLayout.LayoutParams params3 = (RelativeLayout.LayoutParams)b3.getLayoutParams();
params3.addRule(RelativeLayout.RIGHT_OF, 222);
b3.setId(333);
b3.setLayoutParams(params3);
RelativeLayout.LayoutParams params4 = (RelativeLayout.LayoutParams)b4.getLayoutParams();
params4.addRule(RelativeLayout.RIGHT_OF, 333);
b4.setId(444);
b4.setLayoutParams(params4);
RelativeLayout.LayoutParams params5 = (RelativeLayout.LayoutParams)b5.getLayoutParams();
params5.addRule(RelativeLayout.ALIGN_PARENT_START);
params5.addRule(RelativeLayout.BELOW, 111);
b5.setId(555);
b5.setLayoutParams(params5);
RelativeLayout.LayoutParams params6 = (RelativeLayout.LayoutParams)b6.getLayoutParams();
params6.addRule(RelativeLayout.RIGHT_OF, 555);
params6.addRule(RelativeLayout.BELOW, 222);
b6.setId(666);
b6.setLayoutParams(params6);
itemButtonLayout.addView(b1);
itemButtonLayout.addView(b2);
itemButtonLayout.addView(b3);
itemButtonLayout.addView(b4);
itemButtonLayout.addView(b5);
itemButtonLayout.addView(b6);
}
And this gives me a perfect result:
But this is the dynamic solution I came up with, and to me it looks like it is doing the exact same thing but the results come out super wonky:
private void loadItemButtons(){
itemButtonLayout = (RelativeLayout)findViewById(R.id.itemButtonLayout);
itemButtonLayout.removeAllViews();
ArrayList<Item> items = db.getAllActiveItems();
int colCount = 0;
int rowCount = 0;
int i = 0;
while(i < items.size()-1){
ItemButton newItemButton = new ItemButton(this, items.get(i));
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams)newItemButton.getLayoutParams();
newItemButton.setId(i);
if(colCount == 0){
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_START);
}else if(colCount == 1){
layoutParams.addRule(RelativeLayout.RIGHT_OF, i-1);
}else if(colCount == 2){
layoutParams.addRule(RelativeLayout.RIGHT_OF, i-1);
}else if(colCount == 3){
layoutParams.addRule(RelativeLayout.RIGHT_OF, i-1);
}
//If we are in any row except the top row, place in reference to the button above it
if(rowCount != 0){
layoutParams.addRule(RelativeLayout.BELOW, i-4);
}
newItemButton.setLayoutParams(layoutParams);
itemButtonLayout.addView(newItemButton);
if(colCount == 3){
colCount = 0;
rowCount += 1;
}else{
colCount += 1;
}
i++;
}
}
Is anyone able to see what I am doing incorrectly or different from the first example??? Any advice is much appreciated!
The reason this is failing for you is because of the IDs you are using. Android uses "reserved" ids for things like the general content area of the app.
Using your code, I was able to add 1000 to each ID and generate the intended result.
Do note my cleanup below:
private void loadItemButtons(){
itemButtonLayout = (RelativeLayout)findViewById(R.id.itemButtonLayout);
itemButtonLayout.removeAllViews();
List<String> items = itemList;
int colCount = 0;
int rowCount = 0;
// # of items per column
int colSpan = 4;
final int itemListSize = itemList.size();
for (int i = 0; i < itemListSize; i++) {
int id = 1000 + i;
ItemButton newItemButton = new ItemButton(this, items.get(i));
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
newItemButton.setId(id);
if(colCount == 0)
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_START);
else
layoutParams.addRule(RelativeLayout.RIGHT_OF, id-1);
//If we are in any row except the top row, place in reference to the button above it
if(rowCount != 0)
layoutParams.addRule(RelativeLayout.BELOW, id-colSpan);
newItemButton.setLayoutParams(layoutParams);
itemButtonLayout.addView(newItemButton);
if(colCount == colSpan - 1)
rowCount += 1;
colCount = (colCount + 1) % colSpan;
}
}
Also, as mentioned in my comment on the original post, you really should use a gridview for this, it's what it was built for.
I can dig a hole with a pitchfork, but I bet a shovel would work better.
I didn't test the code:
private void loadItemButtons(){
itemButtonLayout = (RelativeLayout)findViewById(R.id.itemButtonLayout);
itemButtonLayout.removeAllViews();
ArrayList<Item> items = db.getAllActiveItems();
int colCount = 0;
int rowCount = 0;
int i = 0;
while(i < items.size())
{
ItemButton newItemButton = new ItemButton(this, items.get(i));
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams)newItemButton.getLayoutParams();
newItemButton.setId(i);
if(colCount == 0)
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_START);
else
layoutParams.addRule(RelativeLayout.RIGHT_OF, i-1);
//If we are in any row except the top row, place in reference to the button above it
if(rowCount != 0){
layoutParams.addRule(RelativeLayout.BELOW, i-4);
}
itemButtonLayout.addView(newItemButton, i, layoutParams);
if(colCount == 3){
colCount = 0;
rowCount += 1;
}else{
colCount += 1;
}
i++;
}
}

Any memory efficient method to play frame animation on Android?

I have a requirement that asks for a looping of 100 images that are around 13kb each. At first I tried to use AnimationDrable and load them programatically like this:
public void animationPlay(){
frameAnimation = new AnimationDrawable();
String index = "00000";
for(int i = 1; i <= 100; i++)
{
if(i<10 ){
index = "0000" + i;
}else if(i< 100){
index = "000" + i;
}else if(i< 10000){
index = "00" + i;
}
String finalString = "acting_10_confetti" + index;
int frameIdentifier = getResources().getIdentifier(finalString, "drawable", getPackageName());
frameAnimation.addFrame(getResources().getDrawable(frameIdentifier), 70);
}
ImageView view = (ImageView) findViewById(R.id.imageView);
view.setBackground(frameAnimation);
frameAnimation.start();
}
The problem is as soon as I add the 10th frame, the app crashes with Out of Memory Error.
Has anyone came across this problem before?

Clicking One Button Effecting All

So, I have this android app that is supposibly a board game. It has multiple buttons on it, and when selected, I want the selected one to gain a boarder. But, for some reason, when pressing one, it selectes everything or just doesn't deselect. What am I forgetting to do or doing wrong? Because logically, it shouldn't change anything other than that tile. Their is no For loop with setImageBitmap!
onClickListener:
//set onCLickListener on each tile
public void setOnClickListenerOnTile(TileClass tileI){
ImageButton tile = (ImageButton) findViewById (tileI.getId());
tile.setOnClickListener(new OnClickListener (){
#Override
public void onClick (View V){
Log.i(TAG, "tileOnClick");
ImageButton tile = (ImageButton) findViewById (V.getId());
/*Following code checks if...
*1. if no tile is selected
*2. if the tile that is clicked is also the one that is selected
*3. if the tile selected is different than the one that is clicked*/
//if 1. happens, then add boarder
if (selectedTile == 0){
Log.i(TAG, "First Choice: 1");
//set tile with boarder
tile.setImageBitmap(modifyTile(1,color.blue, mapTile[findTileById(tile.getId(), mapTile)].tilePic));
//remember what tile is selected
selectedTile = V.getId();
}
//else if 2. happens, then remove boarder
else if (selectedTile == V.getId()){
Log.i(TAG, "First Choice: 2");
//set tile without boarder
tile.setImageBitmap(mapTile[findTileById(tile.getId(), mapTile)].tilePic);
tile.setImageBitmap(blankTileBitmap);
tile.refreshDrawableState();
//remember what tile is selected
selectedTile = 0;
}
//else if 3. happens, then remove the boarder on the selectedTile and add boarder on the clickedTile
else if (selectedTile != V.getId() && selectedTile != 0){
Log.i(TAG, "First Choice: 3");
//remove old boarder
ImageButton tempIB = (ImageButton) findViewById (selectedTile);
tempIB.setImageBitmap(mapTile[findTileById(selectedTile, mapTile)].tilePic);
//add new boarder
tile.setImageBitmap(modifyTile(1,color.blue, mapTile[findTileById(tile.getId(), mapTile)].tilePic));
//remember what tile is selected
selectedTile = V.getId();
}
}
});
}
modifyTile:
//Method function:
//to modify a tile
//modificationNum code:
//1: add boarders
//2: remove boarders
//Param: accepts the type of modifications as first parameter,
//color ID as listed in color resource (not Color),
//and a bitmap of the tile
//
public Bitmap modifyTile (int modificationNum, int color, Bitmap bitmap){
int count, count2;
Log.i(TAG, "modifyTile has been called!");
//first, find out which modification todo
//if modificationNum == 1, then it is to add a border
if (modificationNum == 1){
if (bitmap == null){
Log.i(TAG, "null error");
}
//set tile boarders on the top
for (count = 1; count < tileLength; count++){
bitmap.setPixel(count, 1, getResources().getColor(color));
}
//sides...
for (count = 1; count < (tileLength); count++){
bitmap.setPixel(1, count, getResources().getColor(color));
bitmap.setPixel((tileLength - 1), count, getResources().getColor(color));
}
//set tile boarders on the bottom
for (count = 1; count < tileLength; count++){
bitmap.setPixel(count-1, tileLength-1, getResources().getColor(color));
}
}
getAllTileId:
//get id of every tile (may take a long time) (not done)
public int[] getAllTileId (){
int count, count2;
Log.i(TAG, "getAllTileId has been called!");
//set up variables...
//have to set up a view for TableLayout so that I can find the tile's id using Tags (it has to be it's childs)
View v = (TableLayout) findViewById (R.id.mapTable);
ImageButton imageButton;
int temp, globalCount;
int results[] = new int[50];
for (count = 0, globalCount = 0; count < 9; count++ ){
if (count % 2 == 0){
temp = 6;
}
else{
temp = 5;
}
for (count2 = 0; count2 < temp; count2++, globalCount++){
imageButton = (ImageButton) v.findViewWithTag ("land" + (count + 1) + (count2 + 1));
results[globalCount] = imageButton.getId();
Log.i(TAG, "land #" + (count+1) + (count2+1) + "'s id = " + results[globalCount]);
}
}
Log.i(TAG, "getAllTileId length" + results.length);
return results;
}
findTileById:
//find a tile in an array using it's id
public int findTileById (int id, TileClass[] map){
Log.i(TAG, "findTileById has been called!");
int count=0;
for (count = 0; count < map.length && map[count].getId() != id; count++);
if (count >= map.length){
Log.i(TAG, "findTileById FAIL");
}
return count;
}
EDIT:
Here is onCreate:
//onCreate
#Override
public void onCreate (Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView (R.layout.activity_board);
//**TEST AREA, DELETE AFTER**
//**TEST AREA END**
//get the way to convert from dp to pixels and set up tileLength (in pixels)
metrics = getResources().getDisplayMetrics();
dpToPixels = metrics.density;
tileLength = (int) Math.ceil(44 * dpToPixels);
//set tilePic dimensions
tilePic = new int[tileLength * tileLength];
Log.i(TAG, "tileLength = " + tileLength + " and dpToPixels = " + dpToPixels);
//set up colors
blue = getResources().getColor(R.color.blue);
//set up blank selected tile bitmap
selectedTileBitmap = Bitmap.createBitmap(tileLength, tileLength, Bitmap.Config.ARGB_8888);
//set tile boarders
selectedTileBitmap = modifyTile (1, color.blue, selectedTileBitmap);
//set up blank tile bitmap
blankTileBitmap = Bitmap.createBitmap(tileLength, tileLength, Bitmap.Config.ARGB_8888);
for (count = 0; count < tileLength; count++){
for (count2 = 0; count2 < tileLength; count2++){
blankTileBitmap.setPixel(count, count2, getResources().getColor(color.white));
}
}
//first... get map tile ids...
mapTileId = new int [50];
mapTileId = getAllTileId ();
//set up mapTile
mapTile = new TileClass[50];
for (count = 0; count < 50; count++){
//first... get the tile (which is an ImageButton)
tempIB = (ImageButton) findViewById (mapTileId[count]);
//next step is to create a stringModifier to get the coordinates of the tile through it's tag
stringModifier = new StringBuilder (tempIB.getTag().toString());
//create the tile...
mapTile [count] = new TileClass (tempIB.getId(), Integer.parseInt(stringModifier.substring(4, 5)), Integer.parseInt(stringModifier.substring(5,6)), blankTileBitmap);
Log.i(TAG, "count = " + count);
Log.i(TAG, "test count" + mapTile[count].getId());
}
//set up all the bitmap of the tiles on screen
for (count = 0; count < 50; count++){
tempIB = (ImageButton) findViewById (mapTile [count].getId());
tempIB.setImageBitmap(mapTile[count].tilePic);
}
Log.i(TAG, "Finished setting up mapTile.");
//get id of every tile
//set up each tile with an onClick
for (count = 0; count < 50; count++){
setOnClickListenerOnTile(mapTile[count]);
}
}
Ok, I found my problem.
The user is able to click a button before onCreate is done, which is also before a lot of the arrays that are used to find / initialize other buttons are initialized. So, when the user clicks the button too fast, the array references to every button.

Could not create multiple rows with header(of column and row) in Android

I have problem with creating header of column and row with respective cell values. Only show last position value in both column and row.
ScrollView sv = new ScrollView(this);
TableLayout ll = new TableLayout(this);
HorizontalScrollView hsv = new HorizontalScrollView(this);
String[] row = { "ROW1", "ROW2", "Row3", "Row4", "Row 5", "Row 6", "Row 7" };
String[] column = { "COLUMN1", "COLUMN2", "COLUMN3", "COLUMN4", "COLUMN5", "COLUMN6" };
int nor = row.length;
int noc = column.length;
TextView tv = new TextView(this);
tv.setText("Matrix Implemention Test");
for (int i = 0; i < nor; i++)
{ // for rows
TableRow tbrow = new TableRow(this);
for (int j = 0; j <= noc; j++)
{ // for columns
TextView tv1 = new TextView(this);
String s1 = Integer.toString(i);
String s2 = Integer.toString(j);
String s3 = s1 + s2;
int id = Integer.parseInt(s3);
// tv1[i][j].setId(id);
if (i == 0 & j==0) {
tv1.setText("0=0");
Log.d("TAH", "Display00!!!");
} else if (i == 0) {
for (int r = 0; r < nor; r++) {
tv1.setText(row[r]);
Log.d("TAG", "i==0->"+row[r]);
}
} else if (j == 0) {
for (int c = 0; c < noc; c++) {
tv1.setText(column[c]);
Log.d("TAG", "j==0->"+row[c]);
}
} else {
tv1.setText("Table Cell No=>> " + id);
}
tbrow.addView(tv1);
}
ll.addView(tbrow);
}
hsv.addView(ll);
sv.addView(hsv);
setContentView(sv);
Output like this: I want of respective header of both column and row. first row 1, row 2.... and column 1, column 2....and so on. but only last position value display above code.
change your code to:
for (int i = 0; i < nor; i++) { // for row
TableRow tbrow = new TableRow(this);
for (int j = 0; j <= noc; j++) { // for column
TextView tv1 = new TextView(this);
String s1 = Integer.toString(i);
String s2 = Integer.toString(j);
String s3 = s1 + s2;
int id = Integer.parseInt(s3);
// tv1[i][j].setId(id);
if (i == 0 & j==0) {
tv1.setText("0=0");
Log.d("TAH", "Display00!!!");
} else if (i == 0) {
tv1.setText(column[j]);
} else if (j == 0) {
tv1.setText(row[i]);
} else {
tv1.setText("Table Cell No=>> " + id);
}
tbrow.addView(tv1);
}
ll.addView(tbrow);
}
First thing you seems to have confused columns with rows so i corrected that.
And second notice this for loop:
for (int r = 0; r < nor; r++) {
tv1.setText(row[r]);
Log.d("TAG", "i==0->"+row[r]);
}
is missing.
Here you are first setting row[0] value to tv1 and then row[1] ... so on.
And in the end tv1 has row[6] as the last value.

Categories

Resources