Changing the margins of a textView when binding the view - android

In my layout I have a TextView inside of a RelativeLayout like below:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="80dp"
android:orientation="horizontal">
<TextView
android:id="#+id/textView17"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="70dp"
android:layout_marginStart="70dp"
android:layout_marginTop="12dp"
android:layout_toLeftOf="#+id/imageButton2"
android:layout_toStartOf="#+id/imageButton2"
android:text="TextView"
android:textColor="#android:color/black"
android:textSize="24sp"
android:textStyle="bold" />
The left margins are explicitly set to 70dp in this case. However, I would like to conditionally decrease the left margin to 30dp or so. My attempt to do so is here:
#Override
public void onBindItemViewHolder(RecyclerView.ViewHolder holder, int position) {
final Material m = ...
ViewHolder h = (ViewHolder) holder;
h.checkedImageview.setVisibility(View.GONE);
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) h.titleTextview.getLayoutParams();
layoutParams.setMargins(
20,
layoutParams.topMargin,
layoutParams.rightMargin,
layoutParams.bottomMargin
);
h.titleTextview.setLayoutParams(layoutParams);
^^ However, that is having no effect at all. If I modify the values in the XML layout, will it work without any issue? What am I doing wrong? I'm using the SectionedRecyclerViewAdapter RecyclerView library, if that matters at all.

for example :
public static class PersonViewHolder extends RecyclerView.ViewHolder {
CardView cv;
TextView personName;
TextView personAge;
ImageView personPhoto;
PersonViewHolder(View itemView) {
super(itemView);
cv = (CardView)itemView.findViewById(R.id.cv);
personName = (TextView)itemView.findViewById(R.id.person_name);
personAge = (TextView)itemView.findViewById(R.id.person_age);
personPhoto = (ImageView)itemView.findViewById(R.id.person_photo);
}
}
so i read the git hub page justo do it :
#Override
public void onBindItemViewHolder(PersonViewHolder holder, int position) {
//here --->>>
PersonViewHolder itemHolder = (PersonViewHolder) holder; // important !
holder.checkedImageview.setVisibility(View.GONE);
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) holder.titleTextview.getLayoutParams();
layoutParams.setMargins(
20,
layoutParams.topMargin,
layoutParams.rightMargin,
layoutParams.bottomMargin
);
holder.titleTextview.setLayoutParams(layoutParams);

The issue is that you're reusing the existing LayoutParams from the text view. Instead of reusing, create a new RelativeLayout.LayoutParams object, set its margins, and then set the TextView's params appropriately. Code:
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams
(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
params.setMargins(0, 0, 0, 0); // or any other values
textView.setLayoutParams(params);

Related

How to draw the right the changed RecyclerView element?

There Fragment. Is it RecyclerView attached below. The bottom line is that by design is the first element should take a little more space than the others. His I increase in ViewHolder of the adapter when rendering as follows:
public class myAdapter extends RecyclerView.Adapter ...
...
#Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
WeatherForDay weather = mWeathersList.get(position);
holder.mDayTextView.setText(weather.getDay());
//todo update iconManager
//need icon manager, with input -> String, output ->(R.drawable.icon) int
holder.mIconImageView.setImageResource(R.drawable.testicon1);
holder.mTempTextView.setText(weather.getTmp());
if (position == 0) {
if (isFirstBind) {
Log.d(DEBUG_TAG, "is first bind and first position");
holder.setBig();
isFirstBind = false;
}
}
}
...
public void setBig() {
LinearLayout.LayoutParams param = (LinearLayout.LayoutParams) mRoundLayout.getLayoutParams();
int newHeight = (int) (param.height * 1.2f);
int newWidth = (int) (param.height * 1.2f);
param.height = newHeight;
param.width = newWidth;
mRoundLayout.setLayoutParams(param);
mRoundLayout.setBackgroundDrawable(createBigShape(newHeight));
}
private Drawable createBigShape(int newHW) {
GradientDrawable shape = new GradientDrawable();
shape.setShape(GradientDrawable.RECTANGLE);
shape.setCornerRadii(new float[]{newHW, newHW, newHW, newHW, newHW, newHW, newHW, newHW});
shape.setColor(mContext.getResources().getColor(R.color.weryDark));
shape.setStroke(1, mContext.getResources().getColor(R.color.weryDark));
return shape;
}
...
}
How to make elements are aligned along the upper edge and the lower?
P.S. The same problem arises in that the N-element also somehow rendered "large" (on the same device with a large screen N = 13, on the small screen N = 8)
P.S.2 Can eat what is more optimal way to change any element RecyclerView?
item_recycler.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:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="4dp"
android:layout_marginRight="4dp"
android:gravity="center_horizontal"
android:orientation="vertical">
<TextView
android:id="#+id/day_text_view_list_item_bottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#color/colorWhite"
android:background="#null"/>
<LinearLayout
android:id="#+id/rounded_linear_layout"
android:layout_width="80dp"
android:layout_height="80dp"
android:background="#drawable/round_shape"
android:gravity="center_horizontal"
android:orientation="vertical">
<android.support.v7.widget.AppCompatImageView
android:id="#+id/icon_image_view_list_item_bottom"
android:layout_width="42dp"
android:layout_height="42dp"
android:background="#null"
app:srcCompat="#drawable/testicon1"
tools:ignore="MissingPrefix"/>
<TextView
android:id="#+id/temperature_text_view_list_item_bottom"
android:textColor="#color/colorWhite"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
android:textStyle="bold"/>
</LinearLayout>
</LinearLayout>
For the gravity issue:
You have to set android:layout_gravity="center_vertical" or android:layout_gravity="center" to your item's root element (LinearLayout).
In addition:
Instead of changing LayoutParams manually, I suggest you to use viewType and create different layouts for position 0 and position > 0. This way, you ensure only position 0 item is bigger and you don't modify it's natural functioning.
You would add this method:
private static final int TYPE_BIG = 0;
private static final int TYPE_STANDARD = 1;
#Override
public int getItemViewType(int position) {
return position == 0 ? TYPE_BIG : TYPE_STANDARD;
}
And modify your onCreateViewHolder:
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
int layout = viewType == TYPE_BIG
? R.layout.item_recycler_big
: R.layout.item_recycler;
View v = View.inflate(parent.getContext(), layout, parent);
return new ViewHolder(v);
}
And your onBindViewHolder would be as simple as:
#Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
WeatherForDay weather = mWeathersList.get(position);
holder.mDayTextView.setText(weather.getDay());
holder.mIconImageView.setImageResource(R.drawable.testicon1);
holder.mTempTextView.setText(weather.getTmp());
}
Hope this helps you!
Don't use position that provided from onBindViewHolder(final ViewHolder holder, final int position), it's not permanent (that's why your N-element also "large"). Use holder.getAdapterPosition() instead
Did you try to use some Gravity? For example:
a) Define android:gravity="center_vertical" for RecyclerView item layout
b) Define android:layout_gravity="center_vertical" for mRoundLayout
c) Define android:layout_centerInParent or
android:layout_centerVertical ="true"

Android, RelativeLayout in Adapter is causing ERROR

I am trying to make a chat bubble, I have successfully did it with a text only, but when i want to add another text to put the time inside the bubble i had to add a RelativeLayout to put it on the actual linear layout, but this time i am getting an error.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:transitionGroup="true">
<RelativeLayout
android:id="#+id/my_lay"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="#+id/message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="17sp"
android:text="test"
android:background="#drawable/sender_message_9"/>
<TextView
android:id="#+id/messageTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15sp"
android:text="12:12 PM"
android:layout_alignBottom="#id/message"
android:layout_alignRight="#id/message"
/>
</RelativeLayout>
</LinearLayout>
ADAPTER:
public class ChatAdapter extends ArrayAdapter<MessageProvider> {
private List<Message> list = new ArrayList<>();
private TextView TXT;
private RelativeLayout rLayout;
Context context;
...
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null){
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.source_message, parent, false);
}
...
TXT.setText(Message);
//Set Linear Changes
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
if(!POSITION){ // Moves the layout to the right
params.gravity = Gravity.RIGHT;
}else { // Moves it to the Left
params.gravity = Gravity.LEFT;
}
TXT.setLayoutParams(params);
return convertView;
}
}
ERROR:
05-05 00:10:44.563 8962-8962/com.example.example E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.ClassCastException: android.widget.LinearLayout$LayoutParams cannot be cast to android.widget.RelativeLayout$LayoutParams
I would appreciate any answer, thanks.
change the following line
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
to
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
because you have included the textview inside a RelativeLayout parent.
The error is this line
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
you are using Linear layout params for a Relative Layout.
try using
RelativeLayout.LayoutParams params= new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);

Change layout parameter in bindview in a cursor- Android

I have the following XML
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/background"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingBottom="4dip"
android:paddingRight="4dip" >
<ImageView
android:id="#+id/imageView1"
android:layout_width="32dip"
android:layout_height="32dip"
android:layout_marginLeft="4dip"
android:src="#drawable/test_imag" />
<TextView
android:id="#+id/text2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/imageView1" />
</RelativeLayout>
and the following bindView in a cursor
public void bindView(View view, Context context, Cursor cursor) {
wrapper = (RelativeLayout) view.findViewById(R.id.background);
TextView tview2 = (TextView) view.findViewById(R.id.text2);
ImageView imgview = (ImageView) view.findViewById(R.id.imageView1);
tview2.setText("Test text");
if (cursor.getPosition() % 2 == 0) {
tview2.setBackgroundResource(R.drawable.bubble_left);
} else {
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
tview2.setBackgroundResource(R.drawable.bubble_right);
params.addRule(RelativeLayout.LEFT_OF, R.id.imageView1);
tview2.setLayoutParams(params);
wrapper.setGravity(Gravity.RIGHT);
}
}
I'm trying to do a bubble chat with an image, the IF part is fine, the image is on the rght side of the screen, and, the text is to the left of it.
In the else part I set the gravity to the right and add a rule to set tview2 to the left of the image.
The result of the above made the image go to the right side of the screen but the tview2 has gone, what did I do wrong?
You need to specify params for the imageview as well since you've declared it initially in the xml to be relative to the textview.
imageparams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
The result would be something like this.
else {
RelativeLayout.LayoutParams imageparams = new RelativeLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
imageparams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
imgview.setLayoutParams(imageparams);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
tview2.setBackgroundResource(R.drawable.bubble_right);
params.addRule(RelativeLayout.LEFT_OF, R.id.imageView1);
tview2.setLayoutParams(params);
wrapper.setGravity(Gravity.RIGHT);
}

Android, How to get/set layout parameters?

In my application I have a conversation room. All of my messages should be aligned to right while the rest should be left aligned.
Single row of my list is like this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/llContainer" >
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:background="#drawable/speech_bubble_orange"
android:id="#+id/llGroup" >
<TextView
android:id="#+id/message_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:shadowColor="#color/message_textShadow"
android:shadowDx="1"
android:shadowDy="1"
android:text="Medium Text"
android:textColor="#color/message_textColor"
android:textSize="20sp" />
<TextView
android:id="#+id/message_date"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/temp_date"
android:gravity="right"
android:layout_marginLeft="4dp"
android:layout_marginRight="4dp"/>
</LinearLayout>
</LinearLayout>
getView() of my adapter is like this:
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = myInflater.inflate(R.layout.list_message_row, null);
holder = new ViewHolder();
holder.tvMessageBody = (TextView) convertView.findViewById(R.id.message_text);
holder.tvMessageDate = (TextView) convertView.findViewById(R.id.message_date);
holder.llContainer = (LinearLayout) convertView.findViewById(R.id.llContainer);
holder.llGroup = (LinearLayout) convertView.findViewById(R.id.llGroup);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.tvMessageBody.setText(messageList.get(position).getMessageBody());
String date = messageList.get(position).getSentDate();
holder.tvMessageDate.setText(formatFanciedDate(date));
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) holder.llContainer.getLayoutParams();
try {
if(messageList.get(position).isMine()) {
holder.llGroup.setBackgroundResource(R.drawable.speech_bubble_green);
params.gravity = Gravity.RIGHT;
}
//If not mine then it is from sender to show orange background and align to left
else {
holder.llGroup.setBackgroundResource(R.drawable.speech_bubble_orange);
params.gravity = Gravity.LEFT;
}
holder.llContainer.setLayoutParams(params);
} catch (NullPointerException e) {
e.printStackTrace();
}
return convertView;
}
I think everything should be fine however when I run the application NullPointerException happens and points to params.gravity = Gravity.RIGHT; or params.gravity = Gravity.LEFT; (depends on isMine() method).
What you think? Where is my mistake?
Any suggestion would be appreciated.
getLayoutParams() will return null until the view is attached to its parent.
Try to create the layout params with its constructor rather than using getLayoutParams().
Use RelativeLayout params and set gravity like this, it will work.
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, RelativeLayout.TRUE);
This is working for me in my application.

Setting width of LinearLayout dynamically?

I want to make my own custom "progress bar". I do this by drawing to linear layouts, each with a different color. After that I want to assign a width to each of them to make it look as a progress bar. The thing I am having right now:
XML file of an item of my CustomAdapter (in Gridview):
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#33c2bd" >
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/lineScore"
android:layout_width="20dp"
android:layout_height="2dp"
android:background="#eef05e"
android:paddingLeft="20dp"
android:paddingTop="0dp"
android:paddingBottom="20dp"
android:layout_below="#+id/tvLevelScore"/>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/lineScoreTotal"
android:layout_width="20dp"
android:layout_height="2dp"
android:background="#0d7975"
android:paddingRight="20dp"
android:paddingTop="0dp"
android:paddingBottom="20dp"
android:layout_below="#+id/tvLevelScore"
android:layout_toRightOf="#+id/lineScore"/>
</RelativeLayout>
Then in the CustomAdapter class under the getView method I am trying to set the lineScoreTotal to 80% of the width of the item:
double viewWidth = (double) mView.getWidth();
int widthScoreBar = (int) (viewWidth * 0.8);
LinearLayout ln = (LinearLayout) mView.findViewById(R.id.lineScoreTotal);
ln.layout(0, 2, widthScoreBar, -1);
However, it is doing nothing... Am I applying the wrong code to set the width? Or is my idea of using LinearLayout to draw those "bars" maybe the wrong thing to do?
EDIT getView method:
#Override
public View getView(int position, View v, ViewGroup parent) {
View mView = v;
if (mView == null) {
LayoutInflater vi = (LayoutInflater) getContext().getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
mView = vi.inflate(R.layout.levelselector_item, null);
}
TextView level = (TextView) mView.findViewById(R.id.tvLevel);
TextView levelScore = (TextView) mView.findViewById(R.id.tvLevelScore);
if (mView != null) {
level.setText(Integer.toString(getItem(position).getLevel()));
loadDataBase();
int correctAnswers = myDbHelper.getCorrectAnswers(getItem(position).getLevel());
correctAnswersPrev = 0;
correctAnswersPrev = myDbHelper.getCorrectAnswersPrev(getItem(position).getLevel());
String correct = Integer.toString(correctAnswers);
levelScore.setText(correct + "/60");
level.setTypeface(font);
levelScore.setTypeface(font);
LinearLayout ln = (LinearLayout) mView.findViewById(R.id.lineScoreTotal);
ln.setLayoutParams(new FrameLayout.LayoutParams(10, 10));
}
return mView;
}
Try either way
Without Gravity
ln.setLayoutParams(new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
Or with gravity
ln.setLayoutParams(new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT,1f));
ln.setLayoutParams(new
LayoutParams(widthScoreBar,LayoutParams.WRAP_CONTENT));
Try setting using LayoutParams.

Categories

Resources