Right now, I'm struggling to accomplish something as simple as adding margin space between my child ImageViews within a custom LinearLayout (modified RadioGroup that is designed to take in a custom ImageView that implements Checkable, didn't override onMesarue). Long story short, these images are of a fixed dimension (60x60dip), and since they are dynamic (from the web), I had to add them dynamically like so:
for(int i = 0; i < num; i++){
ImageViewRadioButton childImage = new ImageViewRadioButton(mContext);
float imagehWidthHeight = getResources().getDimension(R.dimen.image_width_and_height);
LinearLayout.LayoutParams imageParams = new LinearLayout.LayoutParams((int) imageWidthHeight, (int) imageWidthHeight);
int imageSpacing = Utils.dipsToPixels(10, mContext);
int innerPadding = Utils.dipsToPixels(5, mContext);
imageParams.leftMargin = imageSpacing;
imageParams.rightMargin = imageSpacing;
childImage.setAdjustViewBounds(true);
childImage.setLayoutParams(imageParams);
childImage.setBackgroundDrawable(getResources().getDrawable(R.drawable.blue_pressed));
childImage.setPadding(innerPadding, innerPadding, innerPadding, innerPadding);
childImage.setClickable(true);
//other non-image properties...
imageContainer.addView(childImage);
}
The only thing that does work is the padding, which it spaces it out properly. However, I am not seeing any space between the padding of each child (margins). Am I doing this correctly, or is there a better way of doing it short of overriding onMeasure to factor in each child's margins?
You had create imageParams but you are not using that parameters in your code instead of imageParams you are using swatchParams parameter. And you had not put a code of swatchParams parameter.
Related
I am using the google vision API and it can return the color scheme of a picture like this:
The API itself returns values to calculate the exact color from the RGB values and to calculate how much of the image contains that color in %.
I am trying to create something like in the first picture. But I have no clue how to do that, so far I just have a listview that gives an overview shown like here.
Does anyone have an idea how I can create a horizontal color scheme in android where I specify all the colors myself? Even a horizontal listview might work with dynamic widths for each color to reflect the percentage.
Thank you!
You can use LinearLayout and dinamically add child views to it with the weight equal to the percentage of the color :
// sample colors
final int color1 = Color.parseColor("#8da921");
final int color2 = Color.parseColor("#1f0929");
final int color3 = Color.parseColor("#f0b991");
// sample color percentages
final int colorPercentage1 = 60;
final int colorPercentage2= 10;
final int colorPercentage3 = 30;
// you should have this layout defined in your xml
final LinearLayout linearLayout = (LinearLayout) findViewById(R.id.linearLayout);
linearLayout.setWeightSum(100);
// create the views
final View view1 = new View(this);
final LinearLayout.LayoutParams viewParams1 = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT);
viewParams1.weight = colorPercentage1;
view1.setLayoutParams(viewParams1);
view1.setBackgroundColor(color1);
final View view2 = new View(this);
final LinearLayout.LayoutParams viewParams2 = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT);
viewParams2.weight = colorPercentage2;
view2.setLayoutParams(viewParams2);
view2.setBackgroundColor(color2);
final View view3 = new View(this);
final LinearLayout.LayoutParams viewParams3 = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT);
viewParams3.weight = colorPercentage3;
view3.setLayoutParams(viewParams3);
view3.setBackgroundColor(color3);
//finally add the views
linearLayout.addView(view1);
linearLayout.addView(view2);
linearLayout.addView(view3);
How to make a horizontal color scheme in android
Simply inflate views with different weights inside of a LinearLayout with Horizontal orientation.
I have to create a stack of images programmatically (because they have to be dynamic).
I want to stack ImageViews like this:
I've tried this, but the images all land up on top of each other:
for(int i=0; i<limit; i++){
dynamicButtons[i] = new ImageView(contextSosFragment);
int offsetLeft = 15 * i;
int offsetTop = 15 * i;
layoutParamsDynamicButton.setMargins(offsetLeft, offsetTop, 0, 0);
dynamicButtons[i].setAdjustViewBounds(true);
dynamicButtons[i].setScaleType(ScaleType.FIT_CENTER);
dynamicButtons[i].setImageResource(R.drawable.img_badge_dynamic_loading);
dynamicButtons[i].setTag(id);
containerDynamicButtons.addView(dynamicButtons[i], layoutParamsDynamicButton);
}
I've even removed the android:gravity="center" from my xml layout file.
I've also tried to add the layout params on the ImageView after setting the margins (dynamicButtons[i].setLayoutParams(layoutParamsDynamicButton);), but I read that that this might not take effect, because the layout params are for the parent and not the child of the container to which I add the ImageViews, that's why I tried to use addView(view, layoutParams).
How can I position the ImageViews like this, programmatically?
SOLUTION:
The solution was that I had to create a new layout params instance for each image - just like Devunwired suggested. However, I also found that I had to change the LinearLayout.LayoutParams to be RelativeLayout.LayoutParams. Only then did the change take effect.
The final for loop looks like this:
for(int i=0; i<limit; i++){
RelativeLayout.LayoutParams layoutParamsDynamicButton = new RelativeLayout.LayoutParams(width, height);
layoutParamsDynamicButton.bottomMargin = (int) getActivity().getResources().getDimension(R.dimen.margin_badges);
int offsetLeft = AppConstants.dynamic_button_offset_multiplier * i;
int offsetTop = AppConstants.dynamic_button_offset_multiplier * i;
layoutParamsDynamicButton.setMargins(offsetLeft, offsetTop, 0, 0);
Log.d(TAG, "offset = "+offsetLeft);
dynamicButtons[i] = new ImageView(contextSosFragment);
dynamicButtons[i].setAdjustViewBounds(true);
dynamicButtons[i].setScaleType(ScaleType.FIT_CENTER);
dynamicButtons[i].setImageResource(R.drawable.img_badge_dynamic_loading);
dynamicButtons[i].setTag(id);
containerDynamicButtons.addView(dynamicButtons[i], layoutParamsDynamicButton);
}
Each view needs its own LayoutParams object. It looks like your code just updates the same LayoutParams instance each time and passes it to addView(). If this is the case, all your views are pointing to the same params when it comes time to do layout...and their margins will all be the last value set.
As a performance optimization, if you are just placing several static images on top of each other, you could achieve the same effect (including the offsets) with a LayerDrawable (docs link) inside a single ImageView. This is the object created by <layer-list> in XML, but since you need to dynamically set the offset you could create one in code as well. Fewer views typically leads to cleaner UI.
I am trying to add many button into Relativelayout or Linearlayout,
Layout
<Relativelayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
>
</Relativelayout>
then in the class
_ll_layout = (RelativeLayout) findViewById(R.id.container);
I only know how add the button dynamically with code.
JSONArray jsonArray = new JSONArray(tmp.getString("productos"));
Button bt[] = new Button[jsonArray.length()]; // size of product
for (int i = 0; i < jsonArray.length(); i ++){
int padding_40dp = (int) (40 * scale + 0.5f);
int margin_10dp = (int) (10 * scale + 0.5f);
int padding_90dp = (int) (90 * scale + 0.5f);
LinearLayout.LayoutParams params = new Relativelayout.LayoutParams(padding_90dp, padding_40dp);
params.setMargins(margin_10dp, 0 , 0, 0);
bt[i] = new Button(DetalleServicioActivity.this);
bt[i].setText(jsonArray.getJSONObject(i).getString("nombre"));
bt[i].setTag(new TagInfo(jsonArray.getJSONObject(i).getString("id_producto")));
bt[i].setTextColor(Color.parseColor("#FFFFFF"));
bt[i].setBackgroundColor(Color.parseColor("#D8D8D8"));
bt[i].setEnabled(false);
bt[i].setId(Integer.parseInt(jsonArray.getJSONObject(i).getString("id_producto")));
bt[i].setLayoutParams(params);
_ll_layout.addView(bt[i]);
}
but the result is
One on another one, but I need something like this:
Edit
If I use LinearLayout with orientation horizontal and gravity center, this happend
Instead of using Relative Layout or Linear Layout I would rather suggest you to create custom flow layout.Custom flow layout will adjust child views accordingly in rows, and will jump the button in new row according to screen width.
Please have a look here : Flow layout example
Happy Coding :)
Instead of RelativeLayout, make use of LinearLayout with orientation as horizontal and add the button in them at run time
As per your design requirement, make sure you have two linear layouts here.
you can use griedlayout for solved your problem
I am adding horizontalScrollView programatically , but when I try to do horizontalScrollView.getMeasuredWidth() it keeps returning 0.
void addCategory(String catTitle) {
mVideos = mShows.get(catTitle);
LinearLayout theLayout = (LinearLayout)findViewById(R.id.activitymain);
TextView textview=(TextView)getLayoutInflater().inflate(R.layout.categorytitle,null);
textview.setTextColor(Color.CYAN);
textview.setTextSize(20);
textview.setText(catTitle);
HorizontalScrollView horizontalScroll = new HorizontalScrollView (this,null);
LinearLayout LL = new LinearLayout(this);
LL.setOrientation(LinearLayout.HORIZONTAL);
LayoutParams LLParams = new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
LL.setLayoutParams(LLParams);
HorizontalGalleryAdapter adapter = new HorizontalGalleryAdapter(this,mVideos);
for (int i = 0; i < adapter.getCount(); i++) {
View item = adapter.getView(i, null, null);
LL.addView(item);
}
horizontalScroll.addView(LL);
int maxScrollX = horizontalScroll.getChildAt(0).getMeasuredWidth()-horizontalScroll.getMeasuredWidth();
AlertDialog alertDialog = new AlertDialog.Builder(this).create();
alertDialog.setTitle("Reset...");
String max= String.valueOf(maxScrollX);
Ok, I see the problem. You create a HorizontalScrollView, add a child to it, and then immediately try to get its measured width.
You cannot do this. You must add the horizontal scroll view to an existing already-drawn view in your activity first, because otherwise it doesn't have set dimensions yet.
Think about how would it know how many pixels WRAP_CONTENT will set the dimension to before its laid out in your view? If you add it to an existing, already-laid-out view in your activity, then that WRAP_CONTENT will actually get converted to some height.
It looks like you kind-of have a loop - horizontalScroll's dimensions depend on its content (WRAP_CONTENT), yet the content's (LinearLayout's) dimensions depend on the horizontalScroll's dimensions. This does not make sense. Perhaps try MATCH_PARENT for at least the width dimensions of your horizontal scroll view. Then, make sure to not look at dimensions until the view has been drawn.
Have a look into typical usage example for HorizontalScrollView:
// read a view's width
private int viewWidth(View view) {
view.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
return view.getMeasuredWidth();
}
....
void getTableRowHeaderCellWidth(){
int tableAChildCount = ((TableRow)this.tableA.getChildAt(0)).getChildCount();
int tableBChildCount = ((TableRow)this.tableB.getChildAt(0)).getChildCount();;
for(int x=0; x<(tableAChildCount+tableBChildCount); x++){
if(x==0){
this.headerCellsWidth[x] = this.viewWidth(((TableRow)this.tableA.getChildAt(0)).getChildAt(x));
}else{
this.headerCellsWidth[x] = this.viewWidth(((TableRow)this.tableB.getChildAt(0)).getChildAt(x-1));
}
}
}
You can also check full details from this nice tutorial: The code of a Ninja.
I was wondering how I could "randomly" place an array of Buttons in a RelativeLayout?
Is it possible to space the buttons around the entire view?
Thanks for your help! I tried using setX() and setY() but they are float numbers and I'm unsure how they place the buttons in proportion to the size of the screen.
You can add layout margins to your buttons. As margins will be interpreted not relative to each other but to the frame, it will in fact position your buttons.
To set the margins you have to set the view's layout params:
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
Random random = new Random();
params.leftMargin = random.nextInt(100);
params.topMargin = random.nextInt(100);
button.setLayoutParams(params);
However this may cause your buttons to overlap, or be outside the Activity, so it's best not to use entirely random values for positions but to perform checks for overlapping and set random ranges according to the device resolution and button size.
To get device display size:
Display display= activity.getWindowManager().getDefaultDisplay();
int width = display.getWidth();
int Height = display.getHeight();
instead do something like this first create a button array and find the respective id...
LayoutParams lp = new LinearLayout.LayoutParams(widthOfButtons,LayoutParams.WRAP_CONTENT);
Button[] buttons;
for(int i=0; i<4; i++) { //suppose you have four buttons
{
String buttonID = "button" + (i+1);
int resID = getResources().getIdentifier(buttonID, "id", getPackageName());
buttons[i] = ((Button) findViewById(resID));
buttons[i].setHeight(yourvalue);
buttons[i].setWidth(yourvalue);
buttons[i].setLayoutParams(lp);
}
hope it works for your