I have a png image something like below and I need to fill its background color according to its capacity.
For example if tank has oil %100 percent of its capacity, background should be yellow , if has %25 , background should be %25 percent yellow and %75 transparent.
Assume that this is a healthbar in a game.
this is what i have in my layout, just a simple imageview in a linearlayout.
Is there any way to achieve this using animation, clip or something ?
<ImageView
android:id="#+id/ivOilTank"
android:layout_width="0dp"
android:src="#mipmap/oilTank"
android:layout_height="match_parent"
android:layout_weight="1">
Change your layout xml to contain-
<FrameLayout
android:layout_width="150dp"
android:layout_height="wrap_content"
android:background="#android:color/black"
>
<View
android:id="#+id/percent_highlight"
android:layout_width="0dp"
android:layout_height="match_parent"
/>
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#mipmap/oilTank"
/>
</FrameLayout>
Now wherever you want to highlight the certain percentage of the image -
View highlight = findViewById(R.id.percent_highlight);
highlight.setBackgroundResource(<Color_id>);//Any color you want to set
ViewGroup.LayoutParams layoutParams = highlight.getLayoutParams();
layoutParams.width = (int) (dpToPixel(150) * 25 / 100.0f);//If you want to set 25%
highlight.setLayoutParams(layoutParams);
where dpToPixel() converts dp to pixels -
public int dpToPixel(float dp) {
final float scale = getResources().getDisplayMetrics().density;
return (int) (dp * scale + 0.5f);
}
Here is my solution,
Since I am not interested in using dp for width property, i looked for another solution. If you want to use dp directly check Shadab Ansari's answer which gave me a clue.
frameLayout
<FrameLayout
android:id="#+id/flOil"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="horizontal"
>
<View
android:id="#+id/progress_view"
android:background="#fc12d108"
android:layout_width="55dp"
android:layout_height="match_parent"
android:layout_margin="1dp"/>
<ImageView
android:id="#+id/ivOil"
android:layout_width="match_parent"
android:src="#mipmap/oilTank"
android:layout_height="match_parent"
>
</ImageView>
</FrameLayout>
Code
ViewTreeObserver vto = ivRate.getViewTreeObserver();
vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener(){
public boolean onPreDraw() {
ivRate.getViewTreeObserver().removeOnPreDrawListener(this);
widthTank = ivRate.getMeasuredWidth();//get the width of the imageView which has oilTank image as dp.
ViewGroup.LayoutParams layoutParams = prgrs.getLayoutParams();
layoutParams.width = (int) (widthTank / (new Random().nextInt(4) + 2));//calculate a width for view which is going to fill background color, random was user for testwill be using desired value.
prgrs.setLayoutParams(layoutParams);
return true;
}
});
Before using widthTank variable , onPreDraw method has to be called so be sure that it is called otherwise it will not be assigned.
Please checkout this example
https://github.com/fanrunqi/WaveProgressView or https://github.com/rathodchintan/Percentage-wise-Image-Filling
this is the best way to fill image
I am using GridLayout(support) for displaying ImageViews in my application. There are 3 columns and 5 rows. The problem is that the cells in the GridLayout automatically get some space between them. I am not setting any padding or margin for the cells. Please refer to the image below. All cells are added dynamically and here is how I add these cells.
Getting Screen Width and Height:
Point size = new Point();
getWindowManager().getDefaultDisplay().getSize(size);
screenWidth = size.x;
screenHeight = size.y;
rowHeight = (int) (screenHeight * 0.2);
Adding View to GridLayout:
GridLayout.LayoutParams params = new GridLayout.LayoutParams(
getSpec(rowColumn[0]), getSpec(rowColumn[1]));
params.height = rowHeight;
if (rowColumn[1].equalsIgnoreCase("col_full")) {
params.width = (int) (screenWidth);
} else if (rowColumn[1].equalsIgnoreCase("col_two_part")) {
params.width = (int) (screenWidth * 0.6);
} else {
params.width = (int) (screenWidth * 0.3);
}
ImageButton image = (ImageButton) imageHashMap
.get(reOrderedButtonsListCopy.get(i));
image.setLayoutParams(params);
gridLayout.addView(image, params);
XML Layout:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res/com.xx.xxx"
android:id="#+id/scrollView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<android.support.v7.widget.GridLayout
xmlns:app="http://schemas.android.com/apk/res/com.xx.xxx"
android:id="#+id/gridlayout_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="2dp"
app:columnCount="3"
app:rowCount="5" >
</android.support.v7.widget.GridLayout>
</LinearLayout>
</ScrollView>
Current result:
The red lines show the spaces in between the cells. Also, there is some space on the left side of GridLayout. I have only given 2dp as layout_margin. Any reasons why this padding occurs?
[EDIT]
Making the following changes removed the spacings.
gridLayout = (GridLayout) findViewById(R.id.gridlayout_main);
gridLayout.setUseDefaultMargins(false);
gridLayout.setAlignmentMode(GridLayout.ALIGN_BOUNDS);
gridLayout.setRowOrderPreserved(false);
Refer to the image below.
Found the solution.
Making the following changes removed the spacings.
gridLayout = (GridLayout) findViewById(R.id.gridlayout_main);
gridLayout.setUseDefaultMargins(false);
gridLayout.setAlignmentMode(GridLayout.ALIGN_BOUNDS);
gridLayout.setRowOrderPreserved(false);
Refer to the image below.
The only solution that worked for me was to add extra columns in the GridLayout like android:columnCount="7" and then the column that needs more width set to 3 or more. The more space you want to give to that column. It then automatically reserves more space for those columns. The whole GridLayout works as a stretching thing. The columnWeight says how much a column can stretch.
I need to be able to rotate whole layouts on the fly (on the click of a button).
I am able to rotate the layouts using, eg. layout.setRotation(270.0f). The problem is, after the rotation, the layout height and width are not matching its parent's.
I have tried inverting height and width like so,
RelativeLayout layout = (RelativeLayout)findViewById(R.id.rootLayout);
LayoutParams layoutParams = layout.getLayoutParams();
int height = layout.getHeight();
int width = layout.getWidth();
layoutParams.height = width;
layoutParams.width = height;
Which does nothing at all.
I am working with sdk 14.
The first image below is the app as it starts. The second one, after a rotation. I wish to fill the black "space". Any help would be appreciated.
The images below show only a button in the layout. However, in reality, the layout are a lot more complex. What I am trying to achieve is "faking" a landscape view.
Edit: Changed images and added descriptions.
Not sure why this is useful, but it's a nice puzzle. Here is something that works for me:
On rotate click, do this:
RelativeLayout mainLayout = (RelativeLayout) findViewById(R.id.main);
int w = mainLayout.getWidth();
int h = mainLayout.getHeight();
mainLayout.setRotation(270.0f);
mainLayout.setTranslationX((w - h) / 2);
mainLayout.setTranslationY((h - w) / 2);
ViewGroup.LayoutParams lp = (ViewGroup.LayoutParams) mainLayout.getLayoutParams();
lp.height = w;
lp.width = h;
mainLayout.requestLayout();
And the layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:id="#+id/main"
android:layout_height="match_parent"
android:background="#ffcc88"
tools:context=".TestRotateActivity" >
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Test"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
/>
<Button
android:id="#+id/rotate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Rotate"
android:layout_centerInParent="true"
/>
</RelativeLayout>
Try this code:
btnRotate.setOnClickListener(new OnClickListener()
{
#SuppressLint("NewApi")
#Override
public void onClick(View v)
{
int orientation = getResources().getConfiguration().orientation;
switch(orientation)
{
case Configuration.ORIENTATION_LANDSCAPE:
llparent.setRotation(270.0f);
RelativeLayout.LayoutParams layoutParams_LandsScape =
new RelativeLayout.LayoutParams(
rlRoot.getHeight(), rlRoot.getWidth());
layoutParams_LandsScape.setMargins(
rlRoot.getTop(), rlRoot.getRight(),
rlRoot.getBottom(), rlRoot.getLeft());
layoutParams_LandsScape.addRule(RelativeLayout.CENTER_IN_PARENT);
llparent.setLayoutParams(layoutParams_LandsScape);
break;
case Configuration.ORIENTATION_PORTRAIT:
llparent.setRotation(270.0f);
RelativeLayout.LayoutParams layoutParams_Portrait =
new RelativeLayout.LayoutParams(
rlRoot.getHeight(), rlRoot.getWidth());
layoutParams_Portrait.setMargins(
0, 0, rlRoot.getBottom(), rlRoot.getLeft());
layoutParams_Portrait.addRule(RelativeLayout.CENTER_IN_PARENT);
llparent.setLayoutParams(layoutParams_Portrait);
break;
}
}
});
}
And XML:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".RotateAnim">
<RelativeLayout
android:id="#+id/rlroot"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#090">
<LinearLayout
android:id="#+id/llParent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#900"
android:gravity="center"
android:orientation="vertical">
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:text="Button"/>
</LinearLayout>
</RelativeLayout>
</RelativeLayout>
Simple and tricky way to make screen orientation along the button click.. with an example..
Here,I'm using the sharedPreference(Im setting an boolean value based on orientation )
Method for button onClick.
public void rotate(View v) {
edt = prefs.edit();
if (!prefs.getBoolean("screen_protrait", true)) {
edt.putBoolean("screen_protrait", true);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
} else {
edt.putBoolean("screen_protrait", false);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
edt.commit();
}
In xml, set an onClick method for rotate button
<Button
android:id="#+id/bt_rotate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:onClick="rotate"
android:text="Rotate" />
Last one, is in onCreate of Activity you want to set the Prefernce from Application..as
prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
Keep coding.. You can achieve your goal...Let me know,if it's working with your scenario.
If you want to literally rotate the screen, you can force a screen orientation.
Otherwise there's no easy way to do what you are trying to do as View.setRotation(float) will always render the View in its "real" bounds and then rotate it! What I suggest is careful consideration of what elements of the layout should be rotated and then to rotate those specifically.
The only true "automatic" way of achieving it would be to create a custom layout that essentially measures, layouts and draws children rotated... Honestly I would only go there if I really, really needed to and it's probably more trouble than it's worth!
// get root layout from activity's XML
LinearLayout mParentLayout = (LinearLayout) findViewById(R.id.activity_main);
// get screen size from DisplayMetrics if you need to rotate before the screen is shown
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
int height = displayMetrics.heightPixels;
int width = displayMetrics.widthPixels;
// if you are rotating after the view was shown
// acquire width and height from the layout's parent's LayoutParams
// calculate offset to move the view into correct position
int offset = (width - height) / 2;
// rotate the layout
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(height, width);
mParentLayout.setLayoutParams(lp);
// 90° clockwise
mParentLayout.setRotation(90.0f);
mParentLayout.setTranslationX(offset);
mParentLayout.setTranslationY(-offset);
It may look like the suggested answer, but this displays how to get dimensions from DisplayMetrics and the calculating the offset for the translation is a little different because that's the only way it worked properly.
i'll suggest you rotate only button rather than rotating the whole layout like
btn_rotate.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v)
{
rotation = AnimationUtils.loadAnimation(MainActivity.this, R.anim.rotate);
rotation.setFillAfter(true);
btn_rotate.startAnimation(rotation);
}
});
rotate.xml
<set>
<rotate
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="0"
android:fromDegrees="270"
android:pivotX="50%"
android:pivotY="50%"
android:startOffset="0"
android:toDegrees="270" />
</set>
try set your layout params to match_parent after rotation:
layout.setRotation(270.0f)
and then
RelativeLayout layout = (RelativeLayout) findViewById(R.id.rootLayout);
layout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
EDIT: get the parentView View parent = layout.getParent(); and set the width and height of the parent view to your layout as you need - in width to height and vice versa.
Android: alternate layout xml for landscape mode
As I can remember, you should define a new layout for the horizontal view. I think this link can help you
Try this code:
(RelativeLayoutOuterFrame) it is the name of your layout.which you want to rotate.
Actually, we are not rotate the layout.we just change height an width value.
int w = RelativeLayoutOuterFrame.getWidth();
int h = RelativeLayoutOuterFrame.getHeight();
ViewGroup.LayoutParams lp = (ViewGroup.LayoutParams) RelativeLayoutOuterFrame.getLayoutParams();
lp.height = w;
lp.width = h;
RelativeLayoutOuterFrame.setGravity(RelativeLayout.CENTER_IN_PARENT);
RelativeLayoutOuterFrame.setGravity(RelativeLayout.CENTER_HORIZONTAL);
RelativeLayoutOuterFrame.requestLayout();
<LinearLayout
android:layout_width="match_parent"
android:layout_height=" "
android:orientation="vertical" >
Here's the thing, lets say i have this LinearLayout that has a width of match_parent, so the width of the LinearLayout depends on the width of the device. What i dont know is how could i set the android:layout_height=" " value to correspond on the value of the android:layout_width="match_parent" so i could have a Square LinearLayout i know i can do this using LayoutParams but is there a way to do it on xml? Thank you guys..
First get screen width
Display mDisplay = activity.getWindowManager().getDefaultDisplay();
int width = mDisplay.getWidth();
int height = mDisplay.getHeight();
Set Size to Layout
LinearLayout layout = (LinearLayout)findViewById(R.id.LayoutID);
// Gets the layout params that will allow you to resize the layout
LayoutParams params = layout.getLayoutParams();
// Changes the height and width to the specified *pixels*
params.height = width;
params.width = width;
layout.setLayoutParams(params);
In XML:
<LinearLayout
android:layout_width="0dp"
android:layout_height="0dp"
android:id="#+id/LayoutID"
android:orientation="vertical" >
I am trying to set the width of my LinearLayout code side. I am trying to find a way that I can size my selectedNavigationItem of my IcsSpinner to the selected item size...when I set the linearLayout in xml to a certain width, this is achieved...but I need dynamic sizing.
<LinearLayout
android:id="#+id/spinner_ll"
android:layout_width="75dp"
android:layout_height="wrap_content"
android:layout_gravity="right" >
<com.actionbarsherlock.internal.widget.IcsSpinner
android:id="#+id/spinner"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>
Is there any way to set the width of the LinearLayout, not the child?
UPDATE...ANSWER:
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams)ll.getLayoutParams();
lp.width = 85; // set this to size...this is arbitrary number for proof of concept
ll.requestLayout();
You can set the layout parameters from code like this:
LinearLayout layout = (LinearLayout) findViewById(R.id.spinner_11);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(100 /* in pixels */, LayoutParams.WRAP_CONTENT);
layout.setLayoutParams(layoutParams);
You can convert dps to pixels in code like this:
int pixelValue = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10 /* in dps */, getResources().getDisplayMetrics());
Take a look at the documentation here: https://developer.android.com/reference/android/util/TypedValue.html#applyDimension(int, float, android.util.DisplayMetrics)