Android, RelativeLayout in Adapter is causing ERROR - android

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);

Related

Android: Unable to inflate EditText in the layout

I am trying to inflate a EditText view inside a RelativeLayout in my Activity.
But getting an error says:
The specified child already has a parent. You must call removeView() on the child's parent first.
My code:
RelativeLayout relLayout= new RelativeLayout(insideActivity);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
relLayout.setLayoutParams(params);
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.holo_edit_text, null);
EditText searchBox = (EditText)view.findViewById(R.id.holo_text);
relLayout.addView(searchBox);
And here is holo_edit_text.xml
<?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">
<EditText
android:id="#+id/holo_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="true" />
</RelativeLayout>
your holo_edit_text.xml should be
<?xml version="1.0" encoding="utf-8"?>
<EditText
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/holo_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="true"
/>
And the way you add it to the view should be like this
EDIT (use getLayoutInflater() instead)
View view = getLayoutInflater().inflate(R.layout.holo_edit_text, null);
//EditText searchBox = (EditText)view.findViewById(R.id.holo_text);
//The last sentence is not neccesary
relLayout.addView(view);
Have you tried this while adding to relative layout
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE);
relLayout.addView(view, params);
Try this..
View child_view = LayoutInflater.from(this).inflate(R.layout.holo_edit_text, null);
relLayout.addView(child_view);
Use a try/catch mechanism.
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (rootView != null) {
((ViewGroup) rootView.getParent()).removeView(rootView);
}
try {
rootView = inflater.inflate(R.layout.your_layout_file_here, container,false);
EditText searchBox = (EditText)rootView.findViewById(R.id.holo_text);
relLayout.addView(searchBox);
} catch (InflateException e) {
}
return rootView;
}
I have fixed my issue by simply setting the LayoutParams to searchBox before adding it to the RelativeLayout. And its working fine.
Thanks all for your response.

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.

Controls overlap when trying to position programmatically using relative layout (Android)

I am trying to create a fragment. In the fragment I plan to place a text view next to it a Spinner control. I tried using this code. However Spinner always is placed over textview to the left of the screen. Can anyone suggest what could be the problem?
Code:
public class FragmentTest extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
RelativeLayout view = (RelativeLayout)inflater.inflate(R.layout.ll2, null);
RelativeLayout lref = (RelativeLayout)view.findViewById(R.id.ll2ll);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(lref.getLayoutParams());
lp.addRule(RelativeLayout.ALIGN_LEFT);
RelativeLayout rl = new RelativeLayout(getActivity());
TextView tv = new TextView(getActivity());
tv.setId(1);
tv.setLayoutParams(lp);
tv.setText("My ");
rl.addView(tv, lp);
Spinner s = new Spinner(getActivity());
lp.addRule(RelativeLayout.RIGHT_OF, tv.getId());
s.setId(2);
String currencyData[] = {"USD",
"EUR","INR"
};
ArrayAdapter<Object> currencyAdapter; currencyAdapter = new ArrayAdapter<Object>(getActivity(), android.R.layout.simple_spinner_item, currencyData);
currencyAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
s.setAdapter(currencyAdapter);
rl.addView(s,lp);
return rl;
}
}
XML file is
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="300dp"
android:layout_height="fill_parent"
android:layout_marginLeft="10sp"
android:layout_marginRight="10sp"
android:layout_marginTop="10sp"
android:isScrollContainer="true"
android:orientation="horizontal" >
<RelativeLayout
android:id="#+id/ll2ll"
android:layout_width="140dp"
android:layout_height="50dp"
android:textSize="#dimen/font_size" />
</RelativeLayout>
When a view is inflated from a XML you will not get the LayoutParams properly. Try using new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(lref.getLayoutParams());
your problem is this, you can't use the same layout parameters for adding all the layouts and modifying the lp.
because the lp is used after you have initialized all the layouts, that means you are using same parameters for all the layouts spinner and textview both.
try using different layout parameters for all the layouts
RelativeLayout.LayoutParams lp
RelativeLayout.LayoutParams lptextview
RelativeLayout.LayoutParams lpspinner
for all of them
if your problem is solved mark my answser as correct

How to add scrollbar or scrollview in android with class java not xml?

How to add scrollbar or scrollview in android with class java not xml this code?
LayoutInflater inflater = (LayoutInflater) getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.srvr, null);
layout = (RelativeLayout) view.findViewById(R.id.relativeLayout1);
RelativeLayout.LayoutParams labelLayoutParams = new RelativeLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
layout.setLayoutParams(labelLayoutParams);
labelLayoutParams = new RelativeLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
labelLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
labelLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
labelLayoutParams.leftMargin=120;
final EditText tt = new EditText(this);
tt.setTag(i);
tt.setText(DisplayName_list[i].toString());
tt.setMinWidth(230);
tt.setMaxWidth(230);
tt.setMaxLines(1);
As I understood well you want to create a ScrollView programatically. You create it as any other views:
ScrollView sc = new ScrollView(this);
sc.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
sc.setFillViewport(true);
And then you have to add to it your view. Make sure that your view you are adding to the ScrollView is a root view.
sc.addView(ROOT_VIEW)
In your case ROOT_VIEW is a layout which is RelativeLayout
include this as parent
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
// Here should b your Layout tag
</ScrollView>
<ScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/scrollView"
android:layout_below="#+id/activity_main_webview"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginTop="40dp" />

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