I need to develop the horizontal split value bar to show the remaining or completed data. There would be 2 horizontal bar - 1 which will have grayed out color and one which will have a filled color by which i need to show some amount of data which user has already used. Please give your input if some of you already have done this.
thanks in advance
private void showBillCycleProgress(int billCycleProgressBarId, int total, int progress, int fillProgressDrawable, int blankProgressDrawable, View view2) {
LinearLayout layout = (LinearLayout) view2.findViewById(billCycleProgressBarId);
layout.removeAllViews();
for (int i = 0; i < total; i++) {
View view = new View(getActivity());
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(35, ViewGroup.LayoutParams.WRAP_CONTENT);
layoutParams.setMargins(0, 0, 3, 0);
view.setLayoutParams(layoutParams);
view.setBackgroundResource(fillProgressDrawable);
if (i >= progress) {
mHandler.postDelayed(new AnonymousClass(this, view, blankProgressDrawable), (long) (((total - i) * 50) + 200));
}
layout.addView(view);
}
}
Related
Subject of interest : Android
After hours of searching I couldn't find or understand how to create ImageView dynamically to store associative data and perform an action depending on the image view clicked.
Let me elaborate ,
I am creating a grid of ImageViews using GridLayout (as gridview examples are too complex for me). I am able to create the grid but still struggling with alignment issues.
So now I have this Grid of ImageViews, but from what I learned, the Id's of these ImageViews are converted to integers at run time. But I need these IDs as I use them to fetch data from server depending on their uniqueness. Is there a way to store other data than the Ids in ImageView Tags?. I come from a web development background where I could use JavaScript easily to create elements with dynamic Ids to refer later and use in queries. So please guide me.
UPDATE:
I tried using the SetId method, and that is when I got this doubt. Because SetId only lets me set IntegerIDs. What if I needed alphanumeric ID to be used later for querying purposes?.
Exam_Screen.Java
public class Exam_Screen extends AppCompatActivity {
GridLayout gridLayout;
public int[] QArray;
private int[] GetQuestionsFromServer() {
return new int[50];
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_exam__screen);
QArray = GetQuestionsFromServer();
AddQuestionsToScrollArea(QArray);
}
public void AddQuestionsToScrollArea(int[] QArray)
{
gridLayout = findViewById(R.id.gridlayout);
gridLayout.removeAllViews();
int total = QArray.length;
int column = 4 ;
int row = total / column;
gridLayout.setColumnCount(column);
gridLayout.setRowCount(row + 1);
//gridLayout
for (int i = 0, c = 0, r = 0; i < total; i++, c++) {
if (c == column) {
c = 0;
r++;
}
ImageView oImageView = new ImageView(this);
oImageView.setScaleX(0.3f);
oImageView.setScaleY(0.3f);
oImageView.setId(i); // I want to set the Ids I get from Server, and use them later
oImageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
oImageView.setAdjustViewBounds(true);
oImageView.setImageResource(R.drawable.new_candidate_image);
GridLayout.LayoutParams lp = new GridLayout.LayoutParams();
lp.width = 30;
lp.height = 30;
lp.topMargin = 5;
lp.bottomMargin = 5;
lp.leftMargin = 5;
lp.rightMargin = 5;
oImageView.setLayoutParams(lp);
GridLayout.Spec rowSpan = GridLayout.spec(GridLayout.UNDEFINED, 1);
GridLayout.Spec colspan = GridLayout.spec(GridLayout.UNDEFINED, 1);
if (r == 0 && c == 0) {
Log.e("", "spec");
Log.d("Column", "value: " + column);
Log.d("rows", "value: " + row);
colspan = GridLayout.spec(GridLayout.UNDEFINED, 1);
rowSpan = GridLayout.spec(GridLayout.UNDEFINED, 1);
}
GridLayout.LayoutParams gridParam = new GridLayout.LayoutParams(
rowSpan, colspan);
gridLayout.addView(oImageView, gridParam);
}
}
}
Relevant Exam Screen Activity XML
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/border">
<GridLayout
android:id="#+id/gridlayout"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</ScrollView>
I am creating a Table of buttons, to control a LED Matrix via Bluetooth.
I have found on the web Brian's Video Tutorials and followed his Dynamic Buttons and Images video to implement this.
Here is the code:
public class DrawerMode extends Activity {
private static final int NUMOFCOL = 15;
private static final int NUMOFROW = 8;
Button buttons[][] = new Button[NUMOFROW][NUMOFCOL];
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Assign content
setContentView(R.layout.activity_draw_mod);
fillTable();
}
private void fillTable() {
TableLayout tableLayout = (TableLayout) findViewById(R.id.drawer_table);
for( int iter_R = 0; iter_R!= NUMOFROW; iter_R++){
TableRow tableRow = new TableRow(this);
tableRow.setLayoutParams(new TableLayout.LayoutParams(TableLayout.LayoutParams.WRAP_CONTENT,TableLayout.LayoutParams.WRAP_CONTENT,1.0f));
tableLayout.addView(tableRow);
for(int iter_C = 0; iter_C != NUMOFCOL; iter_C++){
final int FINAL_COL = iter_C;
final int FINAL_ROW = iter_R;
Button button = new Button(this);
button.setLayoutParams(new TableRow.LayoutParams( TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.MATCH_PARENT, 1.0f));
button.setText("" + iter_C + "," + iter_R);
button.setPadding(0, 0, 0, 0);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
whenBtnClicked(FINAL_COL, FINAL_ROW);
}
});
tableRow.addView(button);
buttons[iter_R][iter_C] = button;
}
}
}
private void whenBtnClicked(int col, int row) {
//Toast.makeText(this, "Button clicked: " + FINAL_COL + "," + FINAL_ROW, Toast.LENGTH_SHORT).show();
Button button = buttons[row][col];
// Lock Button Sizes:
lockButtonSizes();
int newWidth = button.getWidth();
int newHeight = button.getHeight();
Bitmap originalBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_dark_blue);
Bitmap scaledBitmap = Bitmap.createScaledBitmap(originalBitmap, newWidth, newHeight, true);
Resources resource = getResources();
button.setBackground(new BitmapDrawable(resource, scaledBitmap)); // Change text on button:
button.setText(" ");
}
private void lockButtonSizes(){
for (int row = 0; row < NUMOFROW; row++){
for (int col = 0; col < NUMOFCOL; col++){
Button button = buttons[row][col];
int width = button.getWidth();
button.setMinWidth(width);
button.setMaxWidth(width);
int height = button.getHeight();
button.setMinHeight(height);
button.setMaxHeight(height);
}
}
}
}
It works great, but while testing I have found the following issue.
When I click random buttons it works great:
[img]http://i.imgur.com/OYFJ6zJ.png?1[/img]
But when I complete a row (all elements on row are clicked), and I mean any row it starts to rescale the buttons in the whole table:
[img]http://i.imgur.com/ttAz4U0.png?1[/img]
I was thinking that maybe the LayoutParams of the TableRow should be changed, but not sure about that. What am I missing here?
I think you're right about the layout parameters needing to change. This line
tableRow.setLayoutParams(new TableLayout.LayoutParams(TableLayout.LayoutParams.WRAP_CONTENT,TableLayout.LayoutParams.WRAP_CONTENT,1.0f));
would cause the row's height to shrink in size if no button had displayed text, which seems to be what's happening. The TableLayout.LayoutParams does support setting fixed width/height, which you could sensibly calculate by first getting the device's screen width/height and dividing accordingly.
Or, if that gets to cumbersome, you could set -- though this may be too much of a hack -- the default text in the TextViews in the "unset" buttons with some transparent text (e.g., "1,1") so that the height is the same as a set button. This SO answer answer shows how to make transparent text.
I am certain that this is not a good solution for all cases. But just as I thought, the problem was with
button.setLayoutParams(new TableRow.LayoutParams( TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.MATCH_PARENT, 1.0f));
If I understand correctly after the entire row was clicked, since the LayoutParams change according to the MATCH_PARENT value, the TableRow rescales the whole row to meet this criteria,since the height of the entire row is the same now. Not sure if it happens exactly this way, but I think this is the case because of my solution.
My work around is to add specific values for the LayoutParams, instead of leaving it the system to figure it out:
button.setLayoutParams(new TableRow.LayoutParams( 75, 50, 1.0f));
I am aware this is not how it should be done. But since I have a deadline to met soon, I can't spend any more time with it. Most likely the correct way to do this is Jason's suggestion to get the screen size and calculate it. You can do this with:
Display display = getWindowManager().getDefaultDisplay(); Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;
The problem is to come up with a correct formula to calculate this values you can pass to the LayoutParam. If anyone can figure this out please do post your solution and I will accept that answer. At this point I accept Jason's suggestion.
I have a Sudoku grid image loaded into my app, but I'm having a lot of trouble getting EditTexts to appear in each square. When I run the app, the numbers in the EditTexts are hardly visible. I've tried changing the background color and text color and nothing has changed.
/* PROGRAMATICALLY ADD EDITVIEWS via waiting for draw */
layout.getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener()
{
public void onGlobalLayout()
{
layout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
/* not used yet
int height = grid.getMeasuredHeight();
int width = grid.getMeasuredWidth();
int top = grid.getTop();
//int bottom = grid.getBottom();
int left = grid.getLeft();
int square_height = height/9;
int square_width = width/9;*/
for ( int r = 0; r < 9; r++ )
{
for ( int c = 0; c < 9; c++ )
{
text_boxes[r][c] = new EditText(getApplicationContext());
text_boxes[r][c].setId(r+c);
text_boxes[r][c].setText("1");
text_boxes[r][c].setInputType(InputType.TYPE_CLASS_NUMBER);
text_boxes[r][c].setFilters(new InputFilter[] {new InputFilter.LengthFilter(1)});
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
params.setMargins(c*10, r*50, 0, 0);
layout.addView(text_boxes[r][c], params);
text_boxes[r][c].setBackgroundColor(0x0FF00);
}
}
}
});
you didn't remove the listener when you are finished using it, so it can keep being called.
also, about the color of the EditText, you can change it to whatever you wish , by just changing the background of the EditTexts, or use a global style that sets a default background for EditTexts. you can even use this tool
I'm trying to make a dynamic grid layout, it being API 10+ is the part that's been making it slow going. I tried to make it wrap automatically.. but in the end found it easier just to try to force it into a grid pattern using coordinates. This script was working by itself when I did the positioning at time of creation, but now I am trying to loop through each item as a sort. So if one item is deleted, they all float back into a grid without a hole in the middle.
Problem is, it seems the layout parameters are only applying to the last object.
Here's some base variables and onCreate setup:
int screenWidth;
int screenHeight;
int distStep = 130;
int leftPad = 20;
int numCols;
int baseID = 0;
android.util.DisplayMetrics metrics = this.getResources().getDisplayMetrics();
screenWidth = metrics.widthPixels;
screenHeight = metrics.heightPixels;
numCols = (int) (screenWidth - leftPad) / distStep;
int scrRemain = screenWidth - ((numCols * distStep) + leftPad);
distStep += (int) scrRemain / numCols;
Then on to the main function for adding:
public void addObjToLayout() {
RelativeLayout relLay = (RelativeLayout) this.findViewById(R.id.mainWindow);
for(int i = 1; i <= currQuantity; i++){
TextView tv=new TextView(this);
tv.setTextSize(40);
tv.setId(baseID + i);
tv.setPadding(24, 4, 24, 4);
tv.setBackgroundColor(0x110000FF);
tv.setText(String.valueOf(baseID + i)); //Val for debugging
tv.setTextColor(0xFFFFFFFF);
relLay.addView(tv);
}
baseID += currQuantity;
sortLayout();
}
Then the sorting:
public void sortLayout() {
int leftNum = 20;
int topNum = 0;
for(int i = 1; i <= baseID; i++){
TextView tv= (TextView) this.findViewById(baseID);
MarginLayoutParams mp = new MarginLayoutParams(tv.getLayoutParams());
mp.setMargins(leftNum, topNum, 0, 0);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(mp);
tv.setLayoutParams(lp);
leftNum += distStep;
if(leftNum >= distStep * numCols){
leftNum = leftPad;
topNum += distStep;
}
}
}
What I am getting is all the textViews pile up in the top left corner, except the last one which is positioned exactly where it should be. So it seems in my head, the params object isn't applying until the loop ends or something.. but logically I don't see why.
As I said, this worked when I set the params at the get go, problem is mass updating them all at once. I am pretty new to android, so I hope I'm not just doing something stupid.
Thanks for your time
Margin means it will set a gap between the previous view and current view.
When you add view1, view2 and view3 to grid layout and if you remove view2 at some point of time, then the margin for view3 is set according to view1. So, it won't leave empty space in place of view2. Instead of removing view2 at run time, set the background for view2 as null and set the text as empty as below.
textView.setBackground(null);
textView.setText("");
So that the view is still available but looks as deleted.
Started looking into GridView using an extended baseAdapter. Looks promising:
For more (see #2):
http://www.mkyong.com/android/android-gridview-example/
I am trying to add a series of images to the current RelativeLayout at runtime below another TextView. So far, I get it to display partially correct, but not exactly right. I can't get them to move to another row. I hope someone can give me a hand and show me the correct way. The series of image will appear below this TextView(R.id.date):
TextView date = (TextView) findViewById(R.id.date);
//// image view start //////
int photos = Integer.parseInt(total_photo);
RelativeLayout mainLayout = (RelativeLayout) findViewById(R.id.relative_layout_b);
for (int i = 0; i < limit; i++){
final ImageView imageView = new ImageView (this);
imageView.setId(i);
imageView.setImageResource(R.drawable.photo_frame);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
imageView.setPadding(10, 10, 0, 0);
imageView.setAdjustViewBounds(true);
imageView.setMaxHeight(80);
imageView.setMaxWidth(80);
lp.addRule(RelativeLayout.BELOW, R.id.date);
lp.addRule(RelativeLayout.RIGHT_OF, imageView.getId() - 1);
imageView.setLayoutParams(lp);
mainLayout.addView(imageView);
}
Right now, it only display total photo quantity - 1 (i.e.: when there is 5, it only display 4); and I would like to get each row to display 5 and will move to the next row immediately if it reach 6, 11, 16....etc. This layout is nested inside a ScrollView and in a RelativeLayout because I have quite a few views in it. So, I will have to stick with RelativeLayout for this.
If I understood what you're trying to do, see if the code below position the ImageViews like you want(I don't know how efficient it is):
private static final int ROW_ITEMS = 5; // 5 ImageViews per row
// ...
RelativeLayout mainLayout = (RelativeLayout) findViewById(R.id.relative_layout_b);
int limit = 13; // I assume that limit is the number of ImageView that you'll put in the layout
int rows = limit / ROW_ITEMS; // the number of rows that results from limit
int leftOver = limit % ROW_ITEMS; // see if we have incomplete rows
if (leftOver != 0) {
rows += 1;
}
int id = 1000; // the ids of the ImageViews 1000, 1001, 1002 etc
int belowId = R.id.date; // this id will be used to position the ImageView on another row
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++) {
final ImageView imageView = new ImageView(this);
imageView.setId(id);
imageView.setImageResource(R.drawable.ic_launcher);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
imageView.setPadding(10, 10, 0, 0);
imageView.setAdjustViewBounds(true);
imageView.setMaxHeight(80);
imageView.setMaxWidth(80);
if (i == 0) {
lp.addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE);
} else {
lp.addRule(RelativeLayout.RIGHT_OF, imageView.getId() - 1);
}
lp.addRule(RelativeLayout.BELOW, belowId);
imageView.setLayoutParams(lp);
mainLayout.addView(imageView);
id++;
}
belowId = id - 1;
rows--;
}
Also, as kcoppock already said in his comment, it might be worth looking at the GridView for efficiency.