Refresh all view in android? - 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)

Related

Get the position of a view just after an addView()

Everything is in the title. I need to add the view at some point in my relativeLayout but not necessary at the OnCreate method. What I want to do is adding a view when the user click on the RelativeLayout, no problem for that. But I need to know the position of this view as soon as possible after I used addView method. Currently I'm using postDelayed but I need to put a high value to be sure that it is displayed before taking the position of the view. I tried using post but didn't work very well so that's why i use a delayed value. I also tried something with treeObserver some time ago but maybe i used it wrong I don't know because it did not work.
Edit:
Here I create the layout param.
RelativeLayout.LayoutParams laoutparam = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT );
laoutparam.addRule(RelativeLayout.CENTER_IN_PARENT);
Here I create my custom view and add the layoutparam to it:
Button button = (Button)findViewById(R.id.lol);
CustView view = new Bubble(getApplicationContext(), "Press this button", button);
bubble.setLayoutParams(laoutparam);
And then in the constructor of my custom RelativeLayout I do an addView(view).
Thanks for your help.
I hope this helps you with getting view location: https://www.tutorialspoint.com/how-to-get-the-absolute-coordinates-of-a-view-in-android
Example:
int loc[]=new int[2];
yourView.getLocationOnScreen(loc);
int x=loc[0];
int y=loc[1];

Optimize Performance for creating views at runtime

I'm confronted with the Problem of slow Performance...
Just take a case:
RelativeLayout myLayout = (RelativeLayout) findViewById(R.id.myrlLayout);
//Adding now 100 Buttons with 100 TextViews below each Button(just a example)
for(i=0;i<100;i++) {
Button btn = new Button(this);
btn.setId(i+1); //Should be a positive integer
//set LayoutParams for Button
RelativeLayout.Layoutparams btn_layoutparams = new RelativeLayout.LayoutParams....
....
myLayout.addView(btn, btn_layoutparams);
TextView mytv = new TextView(this);
mytv.setid(101+i);
//set LayoutParams for Button with referenced to the Button(because the Textview Needs to be
of Button)
....
myLayout.addView(mytv, tv-layoutparams);
}
Regarding to the high amount of Views programmatically created, my app starts really slow...
I think it's not because of creating a new View, but because of setting the LayoutParamters each time for the view. I can't find a Workaround because my LayoutParams for the TextView for example Need to reference to the button created before. Due to that i'm not really able to create a XML-layout-file or XML-style-file because i can't reference the tv's layoutparameters anchor in the XML-file to the button which does not exist at the Moment. At least i didn't find a way. I hope somebody got an idea how to appreciable improve the Performance when creating such a amount of views at runtime. Every advise is welcome.
Update regarding answere from rom4ek
The Problem is, that i Need to calculate how much views can i add per row before the Screen-width is fully used. That means i Need second LayoutParams to add the next Button below the first Button from the first row. And i also Need to reference to the img-Button added before in the LayoutParams.. so it's not possible to reference LayoutParams to a Button which doesn't exist before the for-loop.Maybe i completely miss something.. Do you have an idea/solution? Thank you for your respond.
If you're setting the same LayoutParams, what if you move RelativeLayout.Layoutparams btn_layoutparams = new RelativeLayout.LayoutParams.... before the cycle? So you will initialize it one time, and then no need to create new LayoutParams every step.

Android: LinearLayout disappears due to spacing using weight?

Right, this is a strange problem I have been toying with for a while now, hopefully maybe I am missing something you guys can draw my attention to!
LinearLayouts seem to be disappearing once I add any spacing using views and defining the weight (a method which works elsewhere in the project).
I have a custom Dialog (extends Dialog). In the onCreate() I use the method setContentView(generateDialog()) which returns a vertical LinearLayout.
The LinearLayout has three elements, one row of four custom category buttons (LinearLayouts), one row of sorting buttons (also LinearLayouts) and one ListView which populates the rest of the dialog and refreshes based on which button is pressed.
All is functional and working fine. Except when I attempt to space the buttons out evenly using my spacer method:
Dialog.java:
LinearLayout catBtns = new LinearLayout(context);
catBtns.setOrientation(LinearLayout.HORIZONTAL);
catBtns.setBackgroundResource(R.drawable.btn_cat_gradient_bg);
catBtns.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT));
catBtns.addView(space(1));
cat1Btn = new CatButton(context,this,act,"CAT1");
catBtns.addView(cat1Btn);
catBtns.addView(space(1));
cat2Btn = new CatButton(context,this,act,"CAT2");
catBtns.addView(cat2Btn);
catBtns.addView(space(1));
cat3Btn= new CatButton(context,this,act,"CAT3");
catBtns.addView(cat3Btn);
catBtns.addView(space(1));
cat4Btn = new CatButton(context,this,act,"CAT4");
catBtns.addView(cat4Btn);
catBtns.addView(space(1));
The space() method:
private View space(int space) {
View view = new View(context);
LinearLayout.LayoutParams p = new LinearLayout.LayoutParams(0,0);
p.weight = space;
view.setLayoutParams(p);
return view;
}
What confuses me is that I have been using this method throughout the project and can't find as to why the category LinearLayout DISAPPEARS COMPLETELY when I add the spacers in between each button.
I use the same technique for the sorting buttons and it works perfectly! I use the same technique in another part of the project using slightly different versions of the same buttons (they are different class files though, because the onClickListener and some other stuff is slightly different)
Anyone have any clue?
I tried to build this in XML and it works fine. A possible difference is, that you do not set any LayoutParams for your buttons. Try something like that for every button:
cat1Btn = new CatButton(context,this,act,"CAT1");
catBtns.addView(cat1Btn, new LinearLayout.LayoutParams(0,0));

Setting LayoutParams twice, no effect?

I'm doing this in Monodroid(C#) but I'm sure most of you understand anyway. I need to move a certain textview in intervalls. The first aligning to its parent left works fine. Then i wait 4 seconds and want it to align right of the parent, which gives no effect at all. It stays left. How come?
Example (C#)
RelativeLayout.LayoutParams newParams = (RelativeLayout.LayoutParams)textView.LayoutParameters;
newParams.AddRule(LayoutRules.AlignParentLeft);
textView.LayoutParameters = newParams;
System.Threading.Thread.Sleep(4000);
RelativeLayout.LayoutParams newParams2 =(RelativeLayout.LayoutParams)textView.LayoutParameters;
newParams2.AddRule(LayoutRules.AlignParentRight);
textView.LayoutParameters = newParams2;
Really odd since it works flawless the 1st time..
after setting new layout parameters, you need to call requestLayout() on your view to take effects.
requestLayout()
Call this when something has changed which has invalidated the layout
of this view. This will schedule a layout pass of the view tree.
so you should call:
textViewToAnimate.requestLayout();

How to bring a view to front without calling bringToFront()?

There is apparently a bug in Android which breaks View.bringToFront.
If I have Views arranged in a GridView and want to bring a View to front by calling bringToFront(), it may get moved to the bottom right position in the GridView.
Something shady is going on there, so I can't use bringToFront(). When I don't call it, everything works fine. But the Views overlap - if I use scale animation to scale up a View, it's partially obscured by the Views to the bottom and to the right.
I've checked out bringToFront's source and it calls parent.bringChildToFront(...)
it's this method
public void bringChildToFront(View child) {
int index = indexOfChild(child);
if (index >= 0) {
removeFromArray(index);
addInArray(child, mChildrenCount);
child.mParent = this;
}
}
it apparently removes the View from itself! Without mercy! Is a ViewGroup so dumb that it can't manage Z-indexes in any other way that shuffling controls around? Obviously when GridView removes its child and then adds it back again, it gets placed at the end of the Grid!
Is there anything I can do to show a View on top of others without resorting to some hacking? One thing that comes to my mind is to create another View above the GridView, which will appear to be above the one I'm trying to bringToFront(), but I don't like this solution.
apparently I missed the android:clipChildren="false" property in GridView. It solves my problem.
Have you tried making the View focusable and just calling requestFocus()?
Calling bringToFront() changes the ordering in the GridView. Try creating an ImageView with an image of the view you want to animate and animate that instead.
Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
view.draw(canvas);
final ImageView imageView = new ImageView(getActivity());
imageView.setImageBitmap(bitmap);
ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(view.getWidth() , view.getHeight());
imageView.setLayoutParams(params);
rootview.addView(imageView);
Add an animation listener to your animation and remove the ImageView at the end of the animation.
From API 21 you can call:
view.setZ(float)
If you target API above 21, you can simply add the attribute android:translationZ="xxx dp" to your XML.
Please note that if you add elevation in views like cardview, you go into the Z axis. And if you want a view come to foreground using this way, you just have to make it higher than the elevation you set.
Example : 6 dp elevation in cardview will require a 7dp in the attribute translationZ of the view you want foreground.

Categories

Resources