Is it possible to draw listview in canvas? - android

now I use canvas(ondraw()) to draw images of my app and if I want to show some
list in center of my app. What should I suppose to do? I have 2 ideas.
Add ListView in Dialog, but the screen is dark, which I don't want it to be.
Add ListView in LinearLayout and make it to Bitmap which I can't draw image, my
code is this following:
ListView modeList = new ListView(context);
modeList.setAdapter(new ImageAdapter(context, objects));
linearlayout = new LinearLayout(context);
linearlayout.setOrientation(LinearLayout.VERTICAL);
linearlayout.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
linearlayout.addView(modeList);
linearlayout.layout(0, 0, 200, 200);
linearlayout.measure((int)Define.getScreenWidth(), (int)Define.getScreenHeight());
linearlayout.setDrawingCacheEnabled(true);
linearlayout.buildDrawingCache(true);
and when I draw
protected void onDraw(Canvas canvas) {
canvas.drawBitmap(linearlayout.getDrawingCache(), 200, 200, null);
}
However, it draws nothing :(

First way deffenately better, you could style Dialog to become borderless and with translucenbt background. Check this link.

+1 vote for the first way. Style your dialog and disable dark background.
Second way is overcomplicated. You better add listview as a child directly to a current window, so it will be drawn on top of all other views, or place all your views in framelayout and add listview to that framelayout, so it will be on top of all previously added views.

Related

Programmatically creating and setting LinearLayout divider

I have a horizontal LinearLayout and I want to have 50 pixels of blank space between its child views. After some research I've found that dividers can do this job. I don't want to use XML but create everything programmatically. Here is my code:
LinearLayout parent = new LinearLayout(getContext());
parent.setOrientation(LinearLayout.HORIZONTAL);
ColorDrawable divider = new ColorDrawable(Color.TRANSPARENT);
divider.setBounds(0, 0, 50, 0);
parent.setDividerDrawable(divider);
parent.setShowDividers(LinearLayout.SHOW_DIVIDER_MIDDLE);
....children are added here to parent...
Unfortunately, it doesn't work. No blank space appears between the children.
Does anyone have an idea what's wrong there?
To answer my own question, ColorDrawable was the culprit. When using ShapeDrawable instead it works fine, i.e. like this:
LinearLayout parent = new LinearLayout(getContext());
parent.setOrientation(LinearLayout.HORIZONTAL);
ShapeDrawable divider = new ShapeDrawable();
divider.setIntrinsicWidth(50);
divider.setAlpha(0);
parent.setDividerDrawable(divider);
parent.setShowDividers(LinearLayout.SHOW_DIVIDER_MIDDLE);

Android: ListView covers everything

I am using a ListView inside a LinearLayout and below that another LinearLayout, which won't show up because the ListView appears to take up all the space.
Code:
listView = new ListView(this);
listView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
listLayout = new LinearLayout(this);
listLayout.setOrientation(LinearLayout.VERTICAL);
listLayout.addView(listView);
listLayout.addView(new NavigationBar(this, "android.intent.action.MAIN", "android.intent.action.MY_ACTIVITY"));
setContentView(listLayout);
NavigationBar is also a LinearLayout containing some buttons.
If added on its one it just play properly if added after the ListView it doesnt display at all.
You should set the weight attribute for the linear layouts or use fixed height for the listview. Please post the xml layout to help understand better.
Change
listView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
to
listView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, 0, 1));
(assuming you've imported LinearLayout's LayoutParams, otherwise it will be new LinearLayout.LayoutParams)
This will mean the list view itself won't take up any vertical space, so the navigation bar can be laid out to how big it wants to be, but then, any free space will be assigned to the list view because it has a weight.
You should also consider not having the navigation bar at the bottom, that is a very iPhone thing to do.

Refresh all view in android?

I working on messaging platform like whatsup.When ı send message ı must update the screen because ı am getting data in db.When i press send button ı must update View.
I googled but ı can not exact solution.Can anybody help me?
EDIT:
my code:
RelativeLayout layout=new RelativeLayout(this);
LayoutParams lparams = new LayoutParams(
1200,LayoutParams.WRAP_CONTENT);
layout.setLayoutParams(lparams);
//layout.setBackgroundResource(R.drawable.bubble);
// Creating a new TextView
TextView tv = new TextView(this);
tv.setText(msgdesc[i]);
layout.setGravity(Gravity.RIGHT);
tv.setPadding(30, 10, 0, 0);
layout.addView(tv);
bubbleLayout.addView(layout);
You will need to call either requestLayout() or invalidate() depend on what you update exactly in your view
If you just need the View to redraw so call invalidate()
If you change the View bounds (e.g. size) call requestLayout()
if you use a listview with a listadapter, then you have to use listadapter.notifyDataSetChanged(); this will update your listview with the new data
Have you try with view.invalidate()? http://developer.android.com/reference/android/view/View.html
Drawing
Drawing is handled by walking the tree and rendering each view that
intersects the invalid region. Because the tree is traversed in-order,
this means that parents will draw before (i.e., behind) their
children, with siblings drawn in the order they appear in the tree. If
you set a background drawable for a View, then the View will draw it
for you before calling back to its onDraw() method.
Note that the framework will not draw views that are not in the
invalid region.
To force a view to draw, call invalidate().
you can try like the reply in this post invalidate the viewgroup:
How to force an entire layout View refresh?
Finally if you have only a TextView in your layout try this:
//Supposing that msgdesc is a class field.
void myRefreshFunction(RelativeLayout l)
{
if(l != null)
{
l.removeAllViews();
TextView tv = new TextView(this);
tv.setText(msgdesc[i]);
layout.setGravity(Gravity.RIGHT);
tv.setPadding(30, 10, 0, 0);
layout.addView(tv);
}
}
see Dianne's answer:
invalidate() just causes the views to be redrawn: http://developer.android.com/reference/android/view/View.html#invalidate()
requestLayout() asks that the views go through a new measure/layout pass (and then redraw): http://developer.android.com/reference/android/view/View.html#requestLayout()
If you're building a messaging app and items are added to some kind of list, I suggest using a RecyclerView and Recyclerview Adapter to achieve what you're trying to do. When the list grows in size, your relative layout won't be scrollabe, a RecyclerView however would. On top of that RecyclerView gives you more performance with very long list because from the name ~Recycle~rView, it recycles previous items and thus increases preformance.
Here's a reasonable tutorial on how to achieve what you want:
https://blog.sendbird.com/android-chat-tutorial-building-a-messaging-ui
(I'm not affiliated with SendBird or anything, it's just the first result when you google: RecyclerView chat example)

ListView background image crop

I have my ListView with image background (it's actually a fragment) but still i have set the background with: getListView().setBackgroundResource(R.drawable.table); I noticed that every time this list shows up bacground image is allways like "fill_parent" also i noticed that listview is fill_parent too but i can fix that with getListView().setPadding() but i cant crop background image. Is there any other way to do it? I need background view with aditional buttons...
the Method setPadding is just affecting the content of the ListView, but not it's container e.g. the Background. So basically the padding produces unused space inside the ListView. If you want to restrict the ListView you can use the margin attribute:
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams (LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
layoutParams.setMargins(30, 20, 30, 0);
Another and in my opinion better way to hava a ListView with a Button below is:
Use a LinearLayout with orientation vertical. Add the ListView and the Button to this layout.
The ListViews height is fill_parent and the Button's wrap_content. Now add to both the layout_weight with value 0 for the Button and 1 for the ListView. The result is that the Button is drawn at the bottom of your screen and the ListView just can expand to the rest of the screen (also its background).

How to display a LinearLayout 100px below the top of the screen?

I have a FrameLayout (all the screen is the FL) wich haves a openGLview and a header image on the top of the screen. Now i want to display a menu of two buttons, created with a LinearLayout.
My LL Menu must be floating on the framelayout, 100px below the top of the screen.
How can i achieve that? i tryed with this code, but is not working properly, the Menu is being displayed 100px below the top of the screen but it is painting the upper part of the menu, and i dont want that, i need that the upper part of the menu it's not painted with the colour of the menu. Must be a floating menu.
I'm sure that there is another way to draw the menu 100px below the top of the screen without painting the upper part of the menu with the colour of the menu.
My code (with the upper part colour problem):
///////////////sub menu de shareit////////////////
LinearLayout sharellContainer = new LinearLayout(this);
sharellContainer.setOrientation(LinearLayout.HORIZONTAL);
LinearLayout sharell = new LinearLayout(this);
sharell.setOrientation(LinearLayout.VERTICAL);
sharell.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
//LinearLayout.LayoutParams sharellParams = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
//sharellParams.gravity=Gravity.CENTER;
sharell.setPadding(10, shareit.getHeight()+80, 10, 10);
sharell.setBackgroundColor(0xFF383838);
//sharell.setLayoutParams(sharellParams);
share= new ImageButton(this);
selector(share, R.drawable.but_share_up,R.drawable.but_share_down);
LinearLayout.LayoutParams shareParams = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
shareParams.setMargins(0, 0, 0, 10); //dejo un espacio entre este botón y el siguiente
share.setLayoutParams(shareParams);
sharell.addView(share);
web= new ImageButton(this);
selector(web, R.drawable.but_web_up,R.drawable.but_web_down);
sharell.addView(web);
sharellContainer.addView(sharell);
sharellContainer.setGravity(Gravity.RIGHT);
//////////////////////////////////////////////////
.
.
.
fl.addView(squareGLSurfaceView);
fl.addView(rl);
fl.addView(sharellContainer);
setContentView(fl);
The problem is that you are using padding rather than margins. Any padding gets the background color of the view, margins do not.
You will have to add the margins to to the LayoutParams that you give to your view.
This will be very easy if you use an XML layout. You can also view what you are creating and set individual properties. This also allows you to separate your logic from your views and adhere to the MVVM design pattern so future updates are easier to perform, giving you a more flexible system.

Categories

Resources