I'm having trouble setting a dynamic background for my widget:
My preferences return a color selected by the user and I would like to apply it to the widget but with a gradient effect. So here's where I am at this moment:
My widget.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/widget_layout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/style_widget"
> ...
My Service.java:
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
remoteViews = new RemoteViews(this.getPackageName(), R.layout.widget);
this.prefs = PreferenceManager.getDefaultSharedPreferences(this);
//this is where I get the color preference value, and create another with some transparency
int color1 = prefs.getInt("background_color", 00000000);
int color2 = Color.argb(22, Color.red(color1), Color.green(color1), Color.blue(color1));
int colors[] = { color1, color2 };
//Create the GradientDrawable:
GradientDrawable gradientDrawable = new GradientDrawable(
GradientDrawable.Orientation.TOP_BOTTOM, colors);
If I do :
remoteViews.setInt(R.id.widget_layout, "setBackgroundColor", color1);
I get the background color changed, but since gradientDrawable isn't an int, how do I apply it to my background via remoteViews?
Well, I've found the answer here:
Setting GradientDrawable through RemoteView
I created an Imageview filling the whole widget, then created a bitmap using my gradientDrawable, then setted the bitmap to the imageview:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/widget_layout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/style_widget"
android:padding="0dip" >
<ImageView
android:id="#+id/bck_image"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="fitXY"
/>
and then in my Service:
GradientDrawable gradientDrawable = new GradientDrawable(
GradientDrawable.Orientation.LEFT_RIGHT, colors);
float dpi = getBaseContext().getResources().getDisplayMetrics().xdpi;
float dp = getBaseContext().getResources().getDisplayMetrics().density;
Bitmap bitmap = Bitmap.createBitmap(Math.round(288 * dp), Math.round(72 * dp), Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
gradientDrawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
gradientDrawable.setCornerRadius(5 * (dpi/160));
gradientDrawable.draw(canvas);
remoteViews.setImageViewBitmap(R.id.bck_image, bitmap);
(I'm very new to Android so I don't know if the code is well formed but for me it works, in case it can help anyone.)
Related
I have a Grid that was generated by a RecyclerView and GridLayoutManager , so in my case I will always have only 9 items on the Grid, so I want them to fill the entire screen. Below is how they look on my screen:
This is the activity_main.xml :
<?xml version="1.0" encoding="utf-8"?>
<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=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rv"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</RelativeLayout>
then, the single_item.xml is :
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="120dp"
android:padding="1dp"
>
<ImageView
android:id="#+id/image_item"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY"
/>
</RelativeLayout>
How I attached the Gridlayoutmanager :
rv = findViewById(R.id.rv);
ImageAdapter imageAdapter = new ImageAdapter(allBitmaps, MainActivity.this);
mLayoutManager = new GridLayoutManager(MainActivity.this, 3);
rv.setLayoutManager(mLayoutManager);
rv.setAdapter(imageAdapter);
So I want the grids to fit well the entire screen, how best can this be done ?
Here is the scenario:
Measure the width & height of the RecycerView before attaching the adapter to it:
Get the desired RecyclerView item width & height by dividing the width & height of the previous step by 3; as you have 3 items horizontally and vertically.
Pass the item width & height to the RecyclerView adapter as parameters and store them as fields.
In activity onCreate():
recyclerView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
#Override
public boolean onPreDraw() {
if (recyclerView.getViewTreeObserver().isAlive())
recyclerView.getViewTreeObserver().removeOnPreDrawListener(this);
float width = (float) recyclerView.getWidth() / 3;
float height = (float) recyclerView.getHeight() / 3;
ImageAdapter adapter = new ImageAdapter(context, width, height, allBitmaps);
recyclerView.setAdapter(adapter);
return true;
}
});
Set the ImageView width & height in the ViewHolder:
class ViewHolder extends RecyclerView.ViewHolder {
ImageView image;
public ViewHolder(#NonNull View itemView) {
super(itemView);
image = itemView.findViewById(R.id.image);
image.getLayoutParams().width = (int) itemWidth;
image.getLayoutParams().height = (int) itemHeight;
}
}
I tested this with just an ImageView as a list item layout:
<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="fitXY" />
Portrait preview:
Landscape preview:
I think if you want those images to fill up the screen, you need to modify the width and height of the image inside your single item.xml
I have this problem where i can not show images (bitmap) from my database in a list on my android studio application.
I can make a picture and save it (base64) in my database and retrieve it.
But i cannot figure out how to show al the images on a display.
I tried to do it with a list adaptor but that doesnt work :/
ArrayList<Bitmap> listData = new ArrayList<>();
while(data.moveToNext()){
//get the value from the database in column 1
//then add it to the ArrayList
byte [] encodeByte =Base64.decode(data.getString(1),Base64.DEFAULT);
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
Bitmap bitmap =BitmapFactory.decodeByteArray(encodeByte, 0, encodeByte.length);
listData.add(bitmap);
}
This is the shortcut way to show multiple view depending on the size of listData.
First add LinearLayout in your_current_activity.xml.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
tools:context=".MainActivity">
</LinearLayout>
In java class
LinearLayout linearLayout = findViewById(R.id.linearLayout);
ArrayList<Bitmap> listData = new ArrayList<>();
for (Bitmap a : listData) {
ImageView image = new ImageView(this);
image.setLayoutParams(new android.view.ViewGroup.LayoutParams(80, 60));
image.setMaxHeight(20);
image.setMaxWidth(20);
image.setImageBitmap(a);
linearLayout.addView(image);
}
Below is my output (Assume I have 5 images in listData)
I have xml gradient drawable resource file here:
file: fg_graidient
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
<gradient
android:type="linear"
android:centerX="0%"
android:startColor="#00020321"
android:centerColor="#F2000000"
android:endColor="#B2020321"
android:angle="45"/>
</shape>
I can the imageview foreground like below:
<ImageView
android:id="#+id/backimg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:scaleType="fitXY"
android:foreground="#drawable/fg_graidient"
/>
But I want to set this drawable foreground for imageview programmatically. Is it possible?
Create programmatically gradient shapes
ShapeDrawable.ShaderFactory sf = new ShapeDrawable.ShaderFactory() {
#Override
public Shader resize(int width, int height) {
LinearGradient lg = new LinearGradient(0, 0, width, height,
new int[]{Color.GREEN, Color.GREEN, Color.WHITE, Color.WHITE},
new float[]{0,0.5f,.55f,1}, Shader.TileMode.REPEAT);
return lg;
}
};
PaintDrawable p=new PaintDrawable();
p.setShape(new RectShape());
p.setShaderFactory(sf);
use
Button btn= (Button)findViewById(R.id.btn);
btn.setBackgroundDrawable((Drawable)p);
Try this snipet:
ImageView img = (ImageView)findViewById(R.id.backimg);
img.setImageResource(R.drawable.fg_graidient);
I'm trying to add Imageviews dynamically and
I would like to create this kind of layout, with ImageViews overlapping, for
my android application.
I don't know how to set the overlapping in java code. I want to use java code becouse I'm adding Imageview dynamically!
this is the code that I did:
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:id="#+id/frame1">
</RelativeLayout>
and this is my java code:
RelativeLayout layout = (RelativeLayout) findViewById(R.id.frame1);
RelativeLayout.LayoutParams params1 = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
mImageView = new ImageView (this);
mImageView.setId(1);
name = "0" + ".jpg";
Bitmap bitmap = BitmapFactory.decodeFile(url_image+name);
params1.addRule(RelativeLayout.ALIGN_PARENT_TOP,1);
params1.addRule(RelativeLayout.ALIGN_PARENT_LEFT,1);
params1.addRule(RelativeLayout.ALIGN_PARENT_START,1);
params1.addRule(RelativeLayout.ALIGN_TOP,1);
mImageView.setImageBitmap(bitmap);
layout.addView(mImageView,params1);
for (int i = 1;i < num_max; i++){
mImageView = new ImageView (this);
mImageView.setId(i+1);
name = String.valueOf(i) + ".jpg";
int id = mImageView.getId() - 1 ;
bitmap = BitmapFactory.decodeFile(url_image+name);
mImageView.setImageBitmap(bitmap);
RelativeLayout.LayoutParams params2 = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
params2.addRule(RelativeLayout.BELOW,id);
params2.addRule(RelativeLayout.ALIGN_START,id);
params2.addRule(RelativeLayout.ALIGN_LEFT,id);
layout.addView(mImageView,params2);
}
If you want to images overlapping each other(as i understood from your question) you should remove this line :
params2.addRule(RelativeLayout.BELOW,id);
If you wanted something else feel free to post comment below this answer
Use relative layout for it
use this code
<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" >
<ImageView
android:id="#+id/iv"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ImageView
android:id="#+id/iv_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignRight="#+id/iv"
/>
</RelativeLayout>
Following is the example of how to achieve it.
MainActivity.Java
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RelativeLayout layout = (RelativeLayout) findViewById(R.id.frame1);
//Add first image view
ImageView mImageView = new ImageView (this);
mImageView.setId(1);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.color1);
RelativeLayout.LayoutParams params1 = new RelativeLayout.LayoutParams(300, 300);
mImageView.setImageBitmap(bitmap);
layout.addView(mImageView,params1);
//Add second image view
ImageView mImageView2 = new ImageView (this);
mImageView2.setId(2);
Bitmap bitmap2 = BitmapFactory.decodeResource(getResources(), R.drawable.color2);
mImageView2.setImageBitmap(bitmap2);
RelativeLayout.LayoutParams params2 = new RelativeLayout.LayoutParams(300,300);
params2.setMargins(150, 150, 0, 0);
layout.addView(mImageView2,params2);
}
}
activity_main.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="com.example.sample.MainActivity" >
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:id="#+id/frame1">
</RelativeLayout>
</RelativeLayout>
Output Screenshot:
Required Images:
I have a class named SeatsPanel where I draw seats (using drawRect) in the onDraw method. The onDraw method uses Canvas as a parameter, but how do you set size of the Canvas? The reason why I'm asking this question is because this class is being inflated in another class. I know that the canvas has the default height and width of the phone, but I need to make it smaller. How can I do this?
Any help would be appreciated.
I've tried to implement a simple application that draws a black rect within the main activity, that is drawn pushing a button. For example, in the MainActivity:
private Button button1;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
button1=(Button)findViewById(R.id.button);
button1.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
switch(v.getId()){
case R.id.button:
LinearLayout ll=(LinearLayout)findViewById(R.id.linearLayout1);
System.out.println(ll.getWidth()+" "+ll.getHeight());
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ll.getWidth(),ll.getHeight());
YourView yourView = new YourView(getBaseContext());
yourView.setBackgroundColor(Color.WHITE);
ll.addView(yourView,params);
break;
}
}
});
}
And in the YourView class:
private Bitmap savedBitmap;
public YourView(Context context) {
super(context);
}
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
System.out.println(canvas.getWidth()+" "+canvas.getHeight());
Paint textPaint = new Paint();
textPaint.setARGB(255, 0, 0, 0);
textPaint.setTextAlign(Paint.Align.RIGHT);
textPaint.setTextSize(11);
textPaint.setTypeface(Typeface.DEFAULT);
canvas.drawColor(Color.WHITE);
System.out.println(canvas.getWidth());
System.out.println(canvas.getHeight());
canvas.drawRect(200, 20, 500, 100, textPaint);
}
The main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Push the button and draw a Rect" />
<Button
android:id="#+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button" />
<LinearLayout
android:id="#+id/linearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</LinearLayout>
Might not be applicable in your case, but this works for me
Bitmap animation = BitmapFactory.decodeResource(mContext.getResources(), resourceId, mBitmapOptions); //Get a bitmap from a image file
// Create a bitmap for the part of the screen that needs updating.
Bitmap bitmap = Bitmap.createBitmap(animation.getWidth(), animation.getHeight(), BITMAP_CONFIG);
bitmap.setDensity(DisplayMetrics.DENSITY_DEFAULT);
Canvas canvas = new Canvas(bitmap);
This sets the canvas to the size of the bitmap