How to Dynamically Set the Position of View in Android

How can I dynamically set the position of view in Android?

For anything below Honeycomb (API Level 11) you'll have to use setLayoutParams(...).

If you can limit your support to Honeycomb and up you can use the setX(...), setY(...), setLeft(...), setTop(...), etc.

How to dynamically adjust View position in onResume (Android / Java)

Found it!! I guess it was a duplicate question, I couldn't find it searching before:

https://stackoverflow.com/a/24035591/14116101

How can I set an ImageView's position dynamically in Constraint Layout

You will need to use a ConstraintSet applied to the ImageView to center it. The documentation for ConstraintSet can be found here.

This class allows you to define programmatically a set of constraints to be used with ConstraintLayout. It lets you create and save constraints, and apply them to an existing ConstraintLayout. ConstraintsSet can be created in various ways...

Perhaps the trickiest thing here is how the view is centered. A good description of the centering technique is here.

For your example, the following code will suffice:

    // Get existing constraints into a ConstraintSet
ConstraintSet constraints = new ConstraintSet();
constraints.clone(layout);
// Define our ImageView and add it to layout
ImageView imageView = new ImageView(this);
imageView.setId(View.generateViewId());
imageView.setImageResource(R.drawable.redlight);
layout.addView(imageView);
// Now constrain the ImageView so it is centered on the screen.
// There is also a "center" method that can be used here.
constraints.constrainWidth(imageView.getId(), ConstraintSet.WRAP_CONTENT);
constraints.constrainHeight(imageView.getId(), ConstraintSet.WRAP_CONTENT);
constraints.center(imageView.getId(), ConstraintSet.PARENT_ID, ConstraintSet.LEFT,
0, ConstraintSet.PARENT_ID, ConstraintSet.RIGHT, 0, 0.5f);
constraints.center(imageView.getId(), ConstraintSet.PARENT_ID, ConstraintSet.TOP,
0, ConstraintSet.PARENT_ID, ConstraintSet.BOTTOM, 0, 0.5f);
constraints.applyTo(layout);

Placing a view inside a layout dynamically at a specific position in Android

I used this to place a image button at a specified location in my relative layout. hope this helps:

RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
layoutParams.leftMargin = (int)(marginLeft);
layoutParams.topMargin = (int)(marginTop);
imageButton.setLayoutParams(layoutParams);

EDIT:

You can do this for other layouts that support positioning of child views. This method works even for lower API versions. Atleast it worked on API 10. :)

Android: Is it possible to dynamically position views horizontally and vertically at the same time?

I achieved it with this lines of code (although without spacing):

<com.google.android.flexbox.FlexboxLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:flexWrap="wrap">

<View
android:layout_width="wrap_content"
android:layout_height="100dp"
android:background="@color/red"
app:layout_flexBasisPercent="50%"
app:layout_flexGrow="1"/>

<View
android:layout_width="wrap_content"
android:layout_height="100dp"
android:background="@color/green_dark"
app:layout_flexBasisPercent="50%"
app:layout_flexGrow="1" />

<View
android:layout_width="wrap_content"
android:layout_height="100dp"
android:background="@color/dark_blue_800"
app:layout_flexBasisPercent="50%"
app:layout_flexGrow="1"/>

</com.google.android.flexbox.FlexboxLayout>

How to manage the position of TextViews dynamically when screen size changes

for your requirement you don't have to use 2 text views for this you can place a spannable string builder on just 1 text and put clickable as well as color property and you are done.

Code:

 TextView textView = findViewById(R.id.tvSample);
SpannableStringBuilder stringBuilder =new SpannableStringBuilder(textView.getText());
stringBuilder.setSpan(new ForegroundColorSpan(Color.BLUE),textView.getText().length()-20,textView.getText().length(),Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
stringBuilder.setSpan(new ClickableSpan() {
@Override
public void onClick(final View view) {
Toast.makeText(MainActivity.this,"Click",Toast.LENGTH_LONG).show();
}
},textView.getText().length()-20,textView.getText().length(),Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(stringBuilder);

Here is example of putting different spans on text view

This is how to set two spans on single text view

How to get Position of an view added dynamically on LinearLayout

You can do it just like that

ViewGroup parent;
int position;

for(int i = 0; i < parent.getChildCount(); ++i) {
int currentViewId = parent.getChildAt(i).getId();

if(currentViewId == wantendViewId) {
position = i;
}
}

That's (in my opinion) the simplest way

Android: Change absolute position of a view programmatically

Use the version of addView that takes LayoutParams:

LayoutParams params = mLayout.generateLayoutParams();
params.x = remoteObject.x;
params.y = remoteObject.y;
mLayout.addView(button, params);

Dynamic position of views in RecyclerView

When implementing a RecyclerView.Adapter, you should strive to first create a single ordered list (or array) that represents your data set. If you can successfully build this list, everything else will become dramatically easier to do.

In order to build your list from the JSON sample you posted, I'd consider two different strategies. The first is to use an array so that you can assign specific indexes:

Object[] items = new Object[vertical.size() + horizontal.size() + ad.size()];

for (VerticalItem item : vertical) {
items[item.position] = item;
}

for (HorizontalItem item : horizontal) {
items[item.position] = item;
}

for (AdItem item : ad) {
items[item.position] = item;
}

The second option is to use a List and then sort the list with a Comparator that compares positions. This will require that each of your three item types have a common superclass with the position field or implements an interface that exposes getPosition() etc.

List<PositionalItem> items = new ArrayList<>();
items.addAll(vertical);
items.addAll(horizontal);
items.addAll(ad);

Collections.sort(items, new Comparator<PositionalItem>() {
@Override
public int compare(PositionalItem lhs, PositionalItem rhs) {
return Integer.compare(lhs.getPosition(), rhs.getPosition());
}
});

Either of these will result in a single, sorted list that has your items in the same order you want to display them. We can now use this to implement the rest of the Adapter.

(This example is assuming you use an Object[] for your list of items. If you use List<PositionalItem> or something similar, obviously the syntax will be slightly different.)

private class MyAdapter extends RecyclerView.Adapter {

private final Object[] items;

public MyAdapter(Object[] items) {
this.items = items;
}

@Override
public int getItemCount() {
return items.length;
}

@Override
public int getItemViewType(int position) {
Object item = items[position];

if (item instanceof VerticalItem) {
return R.layout.newsfeed_vertical;
} else if (item instanceof HorizontalItem) {
return R.layout.newsfeed_horizontal;
} else if (item instanceof AdItem) {
return R.layout.newsfeed_ad;
} else {
throw new IllegalStateException("unexpected item type: " + item);
}
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View itemView = inflater.inflate(viewType, parent, false);

switch (viewType) {
case R.layout.newsfeed_vertical: return new VerticalViewHolder(itemView);
case R.layout.newsfeed_horizontal: return new HorizontalViewHolder(itemView);
case R.layout.newsfeed_ad: return new AdViewHolder(itemView);
default: throw new IllegalStateException("unexpected viewType: " + viewType);
}
}

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
switch (holder.getItemViewType()) {
case R.layout.newsfeed_vertical: verticalView((VerticalViewHolder) holder, position);
case R.layout.newsfeed_horizontal: horizontalView((HorizontalViewHolder) holder, position);
case R.layout.newsfeed_ad: adView((AdViewHolder) holder, position);
default: throw new IllegalStateException("unexpected viewType: " + viewType);
}
}

// ...
}

You'll notice that I've used a trick for view types: use the layout resource id instead of an int constant. There's no need to define your own constants; the resources framework has already created these constants for you!

Anyway, I'm happy to answer any other questions you have. But the major lesson here is to worry about building your list of items first, and then use the list in all of the Adapter methods.


Rather than use ArrayList<Object> it would be better to create an interface for all three of your item types to implement, and use that:

public interface NewsfeedItem {
int getPosition();
}

Now you can add implements NewsfeedItem to the declaration of each of your classes:

public class Vertical implements NewsfeedItem {
// ...
}
public class Horizontal implements NewsfeedItem {
// ...
}
public class Adfeed implements NewsfeedItem {
// ...
}

This will "just work" as long as each of your classes has an int getPosition() method in them. It looks like maybe getPosition() returns a String right now, so either you could change the interface definition to return String or you could change the classes to return int. Either way is fine, as long as all four match each other.

Then, once you have this interface set up, you can change your sorting code to use it:

ArrayList<NewsfeedItem> itemsPos = new ArrayList<>();
itemsPos.addAll(listVertical);
itemsPos.addAll(listHorizontal);
itemsPos.addAll(adList);

Collections.sort(items, new Comparator<NewsfeedItem>() {
@Override
public int compare(NewsfeedItem o1, NewsfeedItem o2) {
return Integer.compare(o1.getPosition(),o2.getPosition());
}
});


Related Topics



Leave a reply



Submit