I have an XML layout looking like this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/parent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_weight="0.1"
android:text="1"/>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/child"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center">
<!-- Define these into code
<TextView android:id="#+id/first"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:text="1"/>
<TextView android:id="#+id/second"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/first"
android:layout_marginLeft="5dp"
android:textSize="20sp"
android:text="1"/>-->
</RelativeLayout>
<TextView
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_weight="0.1"
android:text="1"/>
</LinearLayout>
The TextViews inside LinearLayout are not meant to be changed. RelativeLayout also consists of TextViews which are aligned 5dp away from each other. Unlike the parent layout's ones, they need to be defined inside my Java activity. This is what I have tried:
private View getGeneratedView(String[] texts) {
LayoutInflater inflater =
(LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View parentLayout = inflater.inflate(R.layout.parent, null);
RelativeLayout childLayout = (RelativeLayout) parentLayout.findViewById(R.id.child);
Integer lastViewId = null;
for (String text: texts) {
TextView displayedText = new TextView(this);
displayedText.setText(text);
displayedText.setTextSize(20);
RelativeLayout.LayoutParams params =
new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
if (lastViewId != null) {
params.addRule(RelativeLayout.RIGHT_OF, lastViewId);
params.leftMargin = 5;
}
displayedText.setLayoutParams(params);
lastViewId = displayedText.getId();
childLayout.addView(displayedText);
}
return parentLayout;
}
But what the code above does is putting all of the TextViews in the center, the one on top of the other like so:
(parameter texts was new String[] {"1", "1", "1", "1"})
And this is what I am trying to get:
Can anyone point out what I am doing wrong?
Even though you are generating a new TextView for each string in texts, you do not generate an id for it. As a result, displayedText.getId() will always be -1 (View.NO_ID) and lastViewId will never be other than -1.
To correct the code, you need to generate a new id for each generated TextView. With API 17+, you can use View.generateViewId() to do this.
private View getGeneratedView(String[] texts) {
LayoutInflater inflater =
(LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View parentLayout = inflater.inflate(R.layout.parent, null);
RelativeLayout childLayout = (RelativeLayout) parentLayout.findViewById(R.id.child);
Integer lastViewId = null;
for (String text : texts) {
TextView displayedText = new TextView(this);
// Need API 17+ for generateViewId
displayedText.setId(View.generateViewId());
displayedText.setText(text);
displayedText.setTextSize(20);
RelativeLayout.LayoutParams params =
new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
if (lastViewId != null) {
params.addRule(RelativeLayout.RIGHT_OF, lastViewId);
params.leftMargin = 5;
}
displayedText.setLayoutParams(params);
lastViewId = displayedText.getId();
childLayout.addView(displayedText);
}
return parentLayout;
}
Related
I am currently working at developing an app that requires a dynamically generated GridView. In the layout added to the GridView through an adapter I have a LinearLayout that takes information from an ArrayList and then it should display an ImageView followed by a TextView. I have done that programmatically, but some random space appears between the two of them.
I have tried removing the padding, removing the margin, setting the adjustViewBounds of the image to true and also removing the inner padding of the TextView and none of these things work.
Here is the .xml file containing the LinearLayout to be populated:
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="#drawable/rounded_text_black">
<ImageView
android:id="#+id/separator"
android:layout_width="match_parent"
android:layout_height="2dp"
android:scaleType="fitXY"
android:src="#drawable/horizontal_white_line"
android:layout_centerVertical="true"/>
<LinearLayout
**android:id="#+id/orderLayout"**
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignBottom="#id/separator"
android:orientation="vertical"
android:paddingTop="40dp">
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignTop="#id/separator"
android:orientation="vertical"
android:layout_gravity="center"
android:layout_marginTop="10dp">
<ImageView
android:layout_width="15dp"
android:layout_height="15dp"
android:scaleType="fitXY"
android:src="#mipmap/effects"
android:layout_gravity="center"/>
<TextView
android:id="#+id/moodText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
style="#style/smallText"
android:padding="0dp"/>
<TextView
android:id="#+id/tastesText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
style="#style/smallText"
android:textAllCaps="false"
android:padding="0dp"/>
<TextView
android:id="#+id/tastesText1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
style="#style/smallText"
android:textAllCaps="false"
android:padding="0dp"/>
</LinearLayout>
</RelativeLayout>
Here is the code that generates the image-text pairs:
for(int i = 0; i < 3; i++){
int currentPos = orderSize - i;
if(currentPos >= 0){
LinearLayout container = new LinearLayout(v.getContext());
LinearLayout.LayoutParams containerParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
container.setOrientation(LinearLayout.HORIZONTAL);
container.setGravity(Gravity.RIGHT);
container.setLayoutParams(containerParams);
ImageView img = new ImageView(v.getContext());
LinearLayout.LayoutParams imgParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT);
imgParams.gravity=Gravity.RIGHT;
img.setLayoutParams(imgParams);
img.setPadding(0,0,0,0);
if(order.get(currentPos).delivered){
img.setImageResource(R.drawable.green_circle);
}
else{
img.setImageResource(R.drawable.yellow_circle);
}
TextView txt = new TextView(v.getContext());
txt.setTextColor(Color.WHITE);
txt.setText(order.get(currentPos).orderItem);
txt.setPadding(0,0,0,0);
container.addView(img);
container.addView(txt);
ll.addView(container);
}
And here is the result:
The red rectangle indicates the extra space.
Thank you very much.
I suggest you to create your line item view (green ball and drink name) in an xml layout, checking that all is working fine on a single line.
Then you can change your for cycle as follows:
for(int i = 0; i < 3; i++){
int currentPos = orderSize - i;
if(currentPos >= 0){
// inflate a new instance of view starting from an xml file
View tableLineView = getLayoutInflater().inflate(R.layout.table_line, null);
// Image view
ImageView iv = (ImageView)tableLineView.findViewById(R.id.ball);
if(order.get(currentPos).delivered){
iv.setImageResource(R.drawable.green_circle);
} else{
iv.setImageResource(R.drawable.yellow_circle);
}
// TextView
TextView tv = (TextView)tableLineView.findViewById(R.id.textview);
tv.setText(order.get(currentPos).orderItem);
// add to LinearLayout
ll.addView(tableLineView);
}
}
I can't test it now, if you find problems ask me.
Here you can read a discussion about view inflating
TextView txt = new TextView(this);
LinearLayout.LayoutParams txtParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT);
txt.setLayoutParams(txtParams);
txt.setTextColor(Color.BLACK);
txt.setText("Hello World");
txt.setPadding(0,0,0,0);
Use this and you wont see padding anymore!!
I am working on a chat app and on chat view I have to show message left and right. But as I am pretty new in Android programming, I am not being able to achieve this. Here is what I am getting :
Here is my chatbubble.xml that is being used to show line items.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/bubble_layout_parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<LinearLayout
android:id="#+id/bubble_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/bg_msg1">
<TextView
android:id="#+id/message_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxEms="12"
android:layout_gravity="center"
android:text="Hi! new message"
android:textColor="#android:color/primary_text_light" />
</LinearLayout>
</LinearLayout>
And getView method of ChatApapter.java
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = layoutInflater.inflate(resource, parent, false);
Holder holder = new Holder();
holder.txtMsg = (TextView) view.findViewById(R.id.message_text);
HashMap<String,String> hashMap = new HashMap<String,String>();
hashMap = chats.get(position);
LinearLayout layout = (LinearLayout) view.findViewById(R.id.bubble_layout);
LinearLayout parent_layout = (LinearLayout) view.findViewById(R.id.bubble_layout_parent);
layout.setPadding(20,20,20,20);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT);
params.setMargins(0,0,0,20);
layout.setLayoutParams(params);
if(hashMap.get("is_mine").equals("yes")) {
layout.setBackgroundResource(R.drawable.bg_msg1);
parent_layout.setGravity(Gravity.RIGHT);
} else {
layout.setBackgroundResource(R.drawable.bg_msg2);
parent_layout.setGravity(Gravity.LEFT);
}
holder.txtMsg.setText(hashMap.get("message"));
holder.txtMsg.setTextColor(Color.BLACK);
return view;
}
Here is activity_chat_list.xml that is main list view file which is being used with adapter.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.example.mychatapp.UserChat">
<ListView
android:id="#+id/msgListView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/form"
android:divider="#null"
android:dividerHeight="0dp"
android:paddingBottom="10dp"
android:text="Hello World" />
<LinearLayout
android:id="#+id/form"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:background="#91f1f1f1"
android:paddingBottom="2dp">
<EditText
android:id="#+id/messageEditText"
android:layout_width="252dp"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_toLeftOf="#+id/sendMessageButton"
android:layout_weight="0.72"
android:ems="10"
android:maxHeight="80dp" />
<ImageButton
android:id="#+id/sendMessageButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:background="#drawable/send_button"
android:text="d" />
</LinearLayout>
</RelativeLayout>
So can someone help me to make message left and right.
Thanks in advance.
You should set your layout_gravity to left or right, instead of the gravity.
I'm copying the concept from How to set layout_gravity programmatically?
Example (warning, code is not tested):
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT);
if(hashMap.get("is_mine").equals("yes")) {
layout.setBackgroundResource(R.drawable.bg_msg1);
params.gravity = Gravity.RIGHT;
parent_layout.setParams(params);
} else {
layout.setBackgroundResource(R.drawable.bg_msg2);
params.gravity = Gravity.LEFT;
parent_layout.setParams(params);
parent_layout.setGravity(Gravity.LEFT);
}
Alternatively, you make 2 different XMLs and assign layout_gravity inside the xml itself, and inflate appropriate layout for each row.
Use two different textview left and right for is_mine if is_mine is yes set visbility GONE for the other one and set your text on that textview and vice versa.
Instead of using listview try using dynamic textview :
create new Linear layout like
Lineqarlayout ll =new Linear Layout();
LayoutParams lparams = new LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
TextView tvIncoming=new TextView(this);
tvIncoming.setLayoutParams(lparams);
tvIncoming.setGravity(GRAVITY.RIGHT);
tvIncoming.setText("test");
this.ll.addView(tv);
//similarly tvOutgoing with gravity left
if(hashMap.get("is_mine").equals("yes")) {
tvOutgoing.setBackgroundResource(R.drawable.bg_msg1);
holder.txtMsg.setText(hashMap.get("message"));
} else {
tvincogoing.setBackgroundResource(R.drawable.bg_msg1);
holder.txtMsg.setText(hashMap.get("message"));
}
Let me know if it helps::)
Edit: Use this code(or pseudocode ) in your activity and not in adapter
In your Layout folder, you should create 2 different xml files: rightchatbubble.xml and leftchatbubble.xml with
android:layout_gravity="right"
and
android:layout_gravity="left"
respectively.
In your Adapter you should change the following:
if(hashMap.get("is_mine").equals("yes")) {
layout.setBackgroundResource(R.drawable.bg_msg1);
parent_layout.setGravity(Gravity.RIGHT);
} else {
layout.setBackgroundResource(R.drawable.bg_msg2);
parent_layout.setGravity(Gravity.LEFT);
}
with:
if (hashMap.get("is_mine").equals("yes")) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.leftchatbubble, parent, false);
}
else {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.rightchatbubble, parent, false);
}
and it should work fine.
Obviously, in the main remember to update
YOURadapter.notifyDataSetChanged();
i have an ArrayList of usernames for each username i want to add a xml layout (layout_one_user.xml) and put the username String into each TextView (name_user) present in the layout inflated.
my code in the main Activity is this:
ll_counts = (LinearLayout) findViewById(R.id.ll_counts);
lparams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
LayoutInflater inflater_one_user = MainScreen.this.getLayoutInflater();
View layout_one_user = inflater_one_user.inflate(R.layout.layout_one_user, null);
TextView txt_counts = (TextView) layout_one_user.findViewById(R.id.name_user);
ImageView delete_icon = (ImageView) layout_one_user.findViewById(R.id.icon_delete);
ImageView edit_icon = (ImageView) layout_one_user.findViewById(R.id.icon_edit);
for (int i = 0; i < usernames.size(); i++) {
layout_one_user = new View(this);
txt_counts.setText( usernames.get(i) );
ll_counts.addView(layout_one_user);
}
the layout_one_user is:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="5dp"
>
<ImageView
android:id="#+id/icon_edit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_marginRight="10dp"
android:src="#drawable/ic_edit_black_24dp" />
<ImageView
android:id="#+id/icon_delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="20dp"
android:layout_toLeftOf="#+id/icon_edit"
android:src="#drawable/ic_delete_black_24dp" />
<TextView
android:id="#+id/name_user"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/icon_delete"
android:layout_centerHorizontal="true"
android:text="text"
/>
and the layout in my main is:
<LinearLayout
android:id="#+id/ll_counts"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/action_bar"
android:layout_centerHorizontal="true"
android:orientation="vertical" >
</LinearLayout>
But it doesn't appear anything on the screen.
You inflate your custom layout to layout_one_user:
View layout_one_user = inflater_one_user.inflate(R.layout.layout_one_user, null);
but then, on the very first iteration of your loop, you overwrite this variable with an empty View:
layout_one_user = new View(this);
Thus when you add layout_one_user to your layout, you're adding an "empty view" and you see no result.
It seems to me that you need to inflate a new layout for each user:
for (int i = 0; i < usernames.size(); i++) {
View layout = getLayoutInflater().inflate(R.layout.layout_one_user, ll_counts, false);
TextView textView = (TextView) layout.findViewById(R.id.name_user);
textView.setText(usernames.get(i));
ll_counts.addView(layout);
}
In my android app i have been using the RelativeLayout and inflater. so i need to set the text in textView, which i have used with Inflater, but i cannot set the text by code.
XML file activity_title
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:padding="10dp"
android:layout_height="match_parent"
android:background="#000000" >
<TextView
android:id="#+id/text_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:text="Text" />
</RelativeLayout>
2 xml file
<RelativeLayout
android:id="#+id/rel_container"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentRight="true"
android:layout_alignTop="#+id/linearLayout1"
android:layout_toRightOf="#+id/linearLayout1"
>
</RelativeLayout>
so this is the code, which using the inflater
relativeLayout = (RelativeLayout) findViewById(R.id.rel_container);
((ViewGroup) relativeLayout).removeAllViews();
for (int i = 0; i < titleCalendar.length; i++) {
getApplicationContext();
vi= (LayoutInflater)
getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.activity_title, null);
textViewC = (TextView) v.findViewById(R.id.text_title);
textViewC.setText("sdfsfasfasfasfasf");
textViewC.setTextColor(Color.parseColor("#ffffff"));
final RelativeLayout.LayoutParams params = new
RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,RelativeLayout.LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.BELOW, addcnvrtTime);
textViewC.setLayoutParams(params);
((ViewGroup) relativeLayout).addView(v, 0, params);
}
I cannot see the text, which i set on that textview
This is to get Inflater elements:
LayoutInflater inflater = getLayoutInflater();
View customView = inflater.inflate(R.layout.YOUR_LAYOUT_INFLATER, null);
TextView text = (TextView)customView.findViewById(R.id.YOUR_TEXT_VIEW);
text.setText("BlaBlaBlaBlaBla");
Why not put TextView direct inside the Layout and simply do
TextView text = (TextView)findViewById(R.id.YOUR_TEXT_VIEW);
text.setText("BlaBlaBlaBlaBla");
?
try remove params.addRule(RelativeLayout.BELOW, addcnvrtTime)?
What I am trying to do is create N (in this case 9) copies of the ImageView object R.id.tile, place each of them at different coordinates on the layout, and give each its own unique identifier.
board_layout.xml:
<?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="fill_parent"
android:background="#drawable/backgroundcolor"
android:orientation="vertical" >
<LinearLayout
android:id="#+id/topbar"
... >
<ImageButton
android:id="#+id/imagebutton"
... />
</LinearLayout>
<RelativeLayout
android:id="#+id/board"
android:layout_width="match_parent"
android:layout_height="345dp"
android:layout_centerVertical="true"
android:background="#drawable/wwfboard" >
<view class="languid.legend.xsolver.DrawView"
android:id="#+id/myView"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
<ImageView
android:id="#+id/tile"
android:layout_width="21dp"
android:layout_height="21dp"
android:src="#drawable/tile" />
</RelativeLayout>
</RelativeLayout>
BoardLayout.class:
#Override
protected void onCreate(Bundle savedInstance)
{ super.onCreate(savedInstance);
setContentView(R.layout.board_layout);
LayoutInflater inflater = (LayoutInflater)this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View[] tiles = new ImageView[9];
entire_layout = (RelativeLayout)findViewById(R.layout.board_layout);
for(int i = 0; i<tiles.length; i++){
tiles[i] = (ImageView) inflater.inflate(R.layout.board_layout, null);
tiles[i].setId(1000+i);
params = new RelativeLayout.LayoutParams(-1, 345);
params.leftMargin = 32*2*i;
params.topMargin = 34*2*i;
entire_layout.addView(tiles[i]);
}
...
However, I keep getting "Source not found" errors on the last line: layout.addView(tiles[i]);..
Any ideas why?
(Side question: is RelativeLayout better than AbsoluteLayout if you're working with coordinates?)
Edit:
First create a layout with one ImageView with the properties you like
Example:
create file in res/layout/singleimage.xml
<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/image2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/ic_launcher"
android:contentDescription="Sample"/>
And then inflate the ImageView to get the copies of it like this
View[] tiles = new ImageView[9];
// get reference to LayoutInflater
LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
for(int i = 0; i<tiles.length; i++) {
//Creating copy of imageview by inflating it
ImageView image = (ImageView) inflater.inflate(R.layout.singleimage, null);
tiles[i] = image;
tiles[i].setId(i);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(-1, 345);
params.leftMargin = 32*2*3;
params.topMargin = 34*2*3;
layout.addView(tiles[i]);
}
You have set id to i value here
tiles[i].setId(i);
But you are (incorrectly) trying to get it from your other resource (the one you wanted to 'clone'):
layout.addView(tiles[i] = (ImageView) findViewById(R.id.tile)); // INCORRECT
Instead, set the id manually as above, and then:
layout.addView(tiles[i]);
And there is no need to call findViewById()