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];
Related
I am adding a Compound View on onCreateViewHolder for each data item of the RecycleView.
I need to align to the right or the left according to data item value.
If i set the layout parameters for the view at that method, they are overridden by the values on the xml layout file.
The only solution i can come up with is having 2 different layouts files, but that unnecessary duplicates the files.
Any idea how to accomplish this by code?
Update: i try also at onBindViewHolder, the code below.
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
View v = holder.itemView;
//to simplify i try to aling all to the rigth
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.ALIGN_PARENT_END); //this settins has effect if defined on the layout file
v.setLayoutParams(params);
}
Anything done according to the data of the data item should be done in onBindViewHolder, not in onCreateViewHolder. At creation time you should only set things that will be correct regardless of the actual data bound, or the position it is bound at. All the data and position specific settings get done in onBindViewHolder.
Found out. I assumed that holder.itemView was the Compound View i added. I needed to use findViewById to get the Compound View and set the parameters to that view.
So, the solution was to find Compound View from the itemView like this:
View v = holder.itemView.findViewById(android.R.id.content);
Then apply the parameters to this view as posted in the question.
I want to do something like this:
View v1= new View(this);
v1.setBackgroundResource(R.drawable.pic1);
View v2 = new View(this);
v2.setBackgroundResource(R.drawable.pic2);
v1.addView(v2);
RelativeLayout.LayoutParams params;
rl = (RelativeLayout) findViewById(R.id.activity_main);
rl.addView(v1,params);
I know the code is wrong. It just show how I want to do.
Some websides said that viewGroup may help me to achieve this.
I had tried but never can v2 be shown on the screen.
Does someone can tell me how to achieve this?
Views cannot contain other Views. It simply doesn't work this way in Android.
If you want to place a View inside a different View, the containing View must extend the ViewGroup class.
There are several classes that can help you achieve this:
LinearLayout - if you want your views to be aligned vertically or horizontally.
RelativeLayout - if you want your views to be positioned relative to each-other and/or the container
There a many more.
Hope this helps.
Looks ok but the problem might be that you create a View with no params in a relativelayout. Also I don't know if you can create a View object think it have to be TextView, ImageView or something like that :)
So I am working on a linear layout where i add and remove Imagebuttons dynamically. So everytime an imagebutton is clicked and an action is taken, the imagebutton gets removed and changed with another imagebutton/s. The thing is i'd like to maintain the position of the clicked buttons so i can add a new imagebutton at the same location.
final ViewGroup.LayoutParams lpiv = iv.getLayoutParams();
il.removeView(iv);
int ilBtn = R.drawable.ta;
iv3.setImageResource(ilBtn);
iv5.setImageResource(ilBtn);
iv3.setClickable(false);
iv.setClickable(false);
il.addView(iv5, lpiv);
il.addView(iv3, lpiv);
//iv3.setLayoutParams(lpiv);
Correct me, but wouldnt it be easier just to change the image of the ImageButton instead
of adding a new button? To distinguish the status just check the image or a status variable.
customImageButton.setBackgroundResource(R.drawable.imageName);
this.status = this.NEW_STATUS;
Use LinearLayout.indexOfChild(View child) before you call remove, then call addView(View child, int index) with that index.
Is the code pasted in the question the body of your OnClickListener? If so, just modify it to do something like the following before you call removeView():
float originalX = view.getX();
float originalY = view.getY();
where view is the reference to the ImageButton that's being clicked, and then call setX() and setY() on your new buttons.
Just a heads-up, this will only work if the button being clicked and the ones being added are the same height and with. If they're not, you'll have to do some calculations based on the X/Y of the original one versus the height/width difference to find the same x,y point.
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)
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();