android.widget.LinearLayout cannot be cast to android.widget.TextView - android

I add a ListView on runtime like this:
MainMenue = getResources().getStringArray(R.array.Unit);
// remove all controls
LinearLayout formLayout = (LinearLayout)findViewById(R.id.submenue);
formLayout.removeAllViews();
menueview = new ListView(getApplicationContext());
menueview.setVisibility(ListView.VISIBLE);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
params.gravity = Gravity.RIGHT;
menueview.setLayoutParams(params);
menueview.setAdapter(new submenueadapter(menueview.getContext(), MainMenue));
// Set the on Item
SetMenueOnClick() ;
formLayout.addView(menueview);
and then I add a item click listener like this:
public void SetMenueOnClick() {
menueview.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
final String text = (String) ((TextView)view).getText();
}
});
}
But then I have an error:
06-03 10:59:25.862: E/AndroidRuntime(14732): at android.view.ViewRoot.handleMessage(ViewRoot.java:2109)
android.widget.LinearLayout cannot be cast to android.widget.TextView
at this line:
final String text = (String) ((TextView)view).getText();
Any idea how to get the text in this issue? the adapter looks like this:
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.shortmenue, parent, false);
TextView textView = (TextView) rowView.findViewById(R.id.contents);
textView.setText(values[position]);
// Change icon based on name
String s = values[position];
System.out.println(s);
rowView.setBackgroundResource(R.drawable.alternate_list_color);
return rowView;
}
and R.layout.shortmenue is simple, only a TextView like below:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/contents"
android:textSize="34dp"
/>
</LinearLayout>

Your row is a TextView wrapped by a LinearLayout so you might want to do this:
LinearLayout ll = (LinearLayout) view; // get the parent layout view
TextView tv = (TextView) ll.findViewById(R.id.contents); // get the child text view
final String text = tv.getText().toString();

If you are running on a similar problem but you sure you have targeted a linearLayout:
Delete the file gen/your.app.package/R.java.
This happens because of a xml bug, when you delete R.java it will be recreated on the next build/run.

I just added android:id="#+id/my_layout" to LinearLayout that wrapped TextView and that solved similar problem.

I had the same problem and I just renamed inserted view object.
Like this:
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/newTextViewName"
android:textSize="34dp"
/>

In my case an XML contained a TextView, but I made a mistake writing
final TextView text = (TextView) inflater.inflate(R.layout.item_text, layout);
instead of
final TextView text = (TextView) inflater.inflate(R.layout.item_text, layout, false);

You can resolve this by replacing
final String text = (String) ((TextView)view).getText();
with
TextView temp= (TextView) view.findViewById(R.id.textView);
This works for me.

Related

How to add more than one textView to listView

I am using an custom adapter and I have the problem with getView method. Here is my code -
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View vi = convertView;
if (vi == null)
vi = inflater.inflate(R.layout.list_item, null);
if(position==0){
TextView text1 = (TextView) vi.findViewById(R.id.text1);
text1.setText(data[position]);
}else if(position==1){
TextView text2 = (TextView) vi.findViewById(R.id.text2);
text2.setText(data[position]);
}
return vi;
}
and here is the XML file -
<?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="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAlignment="center"
android:background="#android:color/black"
android:textColor="#android:color/white"
android:id="#+id/text1" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAlignment="center"
android:background="#android:color/green"
android:textColor="#android:color/white"
android:id="#+id/text2" />
</LinearLayout>
Actually my if command is working but the other blank textView also appears with it.
Suppose If position==0 then "#+id/text1" should be displayed, but "#+id/text2" also get displayed with no text.
I want only one textview to be displayed, not the other one. How to do that?
position is the index of the currently displayed item in the adapter, not which TextView is being displayed.
Each row of your Adapter has two TextViews, and I assume you have some string that needs to be displayed in both views.
As an example, try this instead.
#Override
public View getView(int position, View convertView, ViewGroup parent) {
String item = String.valueOf(data[position]);
View v = convertView;
if (v == null) {
v = inflater.inflate(R.layout.list_item, null);
}
TextView text1 = (TextView) v.findViewById(R.id.text1);
TextView text2 = (TextView) v.findViewById(R.id.text2);
text1.setText("1: " + item);
text2.setText("2: " + item);
return v;
}
I want only one textview to be displayed, not the other one. How to do that?
Then it sounds like you don't want two TextViews in one layout...
If you question is literally "How to display more than one TextView in a ListView", then you should put more than one value into that data array.

Inflate layout and use its child items

I have a layout where I want to imitate a listview by adding items programmatically one below the other. So I created an .xml for the layout of these items that are something like this:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/ll_lista"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="1dp"
android:layout_marginTop="5dp"
android:layout_toLeftOf="#+id/rellay_btn"
android:orientation="vertical" >
<TextView
android:id="#+id/tv_username"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="1dp"
android:text="Some name"
android:textColor="#3F3F3F"
android:textSize="17sp"
android:textStyle="bold" />
<TextView
android:id="#+id/tv_tip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/iv_follow"
android:text="Some text"
android:textColor="#3F3F3F"
android:textSize="13sp" />
</LinearLayout>
In the activity I would like to generate n of this layout, fill the textviews with text and also I would like to set an onClickListener on them. n is the size of an array. Please help
Note: Once the activity loads, the number of layouts will not change, nor can a layout be removed.
This is what I have now but the layout is displayed on top of the activity instead of below a Textview:
LayoutInflater inflater = LayoutInflater.from(BucketProfileActivity.this);
for (int i = 0; i < 3; i++) {
View view = inflater.inflate(R.layout.bucketprofile_tips, null);
view.setId(i);
TextView tv_username = (TextView) view.findViewById(R.id.tv_username);
tv_username.setText(String.valueOf(i));
RelativeLayout.LayoutParams rl = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
rl.addRule(RelativeLayout.BELOW, R.id.tv_nemkell);
addContentView(view, rl);
}
If your posted xml file is bucketprofile_tips.xml then you need to change here from
TextView tv_username = (TextView) view.findViewById(R.id.tv_title);
to
TextView tv_username = (TextView) view.findViewById(R.id.tv_username);
Because in bucketprofile_tips.xml tv_title id not found for your TextView. So you are getting Null Pointer Exception.
Not sure why you would want to do this but you can just use a LayoutInflater to inflate x of this view and add them to a designated ViewGroup. For example:
LayoutInflater inflater = LayoutInflater.from(context);
for (int i = 0; i < numberOfViews; i++) {
View v = inflater.inflate(R.layout.view_to_add, parentView, false);
setup(v);
parentView.addView(v);
}
Where setup() is a function you define that does the setup work such as setting the text of a TextView etc.
For instance, in your setup function might look something like this:
private void setup(View v) {
TextView tv = (TextView) v.findViewById(R.id.name);
// set the text of the text view
tv.setText("Hello!");
// set the click listener for the view...
v.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// do stuff here...
}
});
}
LinearLayout parentLayout=findViewById(R.id.parentLayout);
LayoutInflater inflater = LayoutInflater.from(BucketProfileActivity.this);
View view = inflater.inflate(R.layout.bucketprofile_tips, null);
parentLayout.addView(view);
LinearLayout textList=(LinearLayout) parentLayout.getChildAt(0);
for(int i=0; i<textList.getChildCount(); i++){
TextView tv_username=(TextView) textList.getChildAt(i);
textView.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view){
tv_username.setText(String.valueOf(i));
}
}
}

How to create customs views dynamically?

I'm trying to find a way to create a custom views dynamically, but I didn't find a useful post for my problem.
I have the next view.
And this is the tree of the layout:
I want to create as many copies as items received, but I need to change the textviews inside per each item.
I don't know If I have explained me well. Thank you.
EDIT:
I follow some of your advises, and I make this:
private void addInputHeader(int timestamp)
{
LinearLayout mRootLayout = (LinearLayout) findViewById(R.id.event_container);
View mChildView = getLayoutInflater().inflate(R.layout.program_event_day_header, mRootLayout, false);
ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
mRootLayout.addView(mChildView, params);
TextView tv_day = (TextView) mChildView.findViewById(R.id.tv_day);
tv_day.setText(getDayForHeader(timestamp) + getResources().getString(R.string.of) + getMonthForHeader(timestamp));
}
private void addInputDescription(int timestamp, String description)
{
LinearLayout mRootLayout = (LinearLayout) findViewById(R.id.event_container);
View mChildView = getLayoutInflater().inflate(R.layout.program_event_day_header, mRootLayout, false);
ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
mRootLayout.addView(mChildView, params);
TextView tv_event_hour = (TextView) mChildView.findViewById(R.id.tv_event_hour);
TextView tv_event_message = (TextView) mChildView.findViewById(R.id.tv_event_message);
tv_event_hour.setText(getHour(timestamp) + " - ");
tv_event_message.setText(description);
}
private String getDayForHeader(long timeStamp){
Date df = new Date(timeStamp*1000);
return new SimpleDateFormat("cccc dd").format(df);
}
private String getMonthForHeader(long timeStamp){
Date df = new Date(timeStamp*1000);
return new SimpleDateFormat("MM").format(df);
}
private String getHour(long timeStamp){
Date df = new Date(timeStamp*1000);
return new SimpleDateFormat("HH:mm").format(df);
}
private int getD(long timeStamp){
Date df = new Date(timeStamp*1000);
return Integer.parseInt(new SimpleDateFormat("dd").format(df));
}
private int getM(long timeStamp){
Date df = new Date(timeStamp*1000);
return Integer.parseInt(new SimpleDateFormat("MM").format(df));
}
private int getY(long timeStamp){
Date df = new Date(timeStamp*1000);
return Integer.parseInt(new SimpleDateFormat("yyyy").format(df));
}
But I'm getting a NullPointerException when the addInputDescription tries to set text on tv_event_hour.
// Add row view layout that represent ui row.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="#+id/leftTop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Left Top" />
<TextView
android:id="#+id/RightTop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Right Top" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="#+id/leftBottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Left Bottom" />
<TextView
android:id="#+id/RightBottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Right Bottom" />
</LinearLayout>
</LinearLayout>
// Add view as row with msg
private void addMsg() {
View msgView = getViewWithMsg("TopLeft", "TopRight", "LeftBottom", "Right Bottom");
// msgView represent one row
// You can add it to linearlayout desendent to scrollview
}
// This method create one msg row layout and update msg
private View getViewWithMsg(String TopLeft, String TopRight, String LeftBottom,
String RightBottom) {
LayoutInflater inflator = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View root = inflator.inflate(R.layout.row, null);
TextView topLeft = (TextView) root.findViewById(R.id.leftTop);
TextView topRight = (TextView) root.findViewById(R.id.RightTop);
TextView bottomLeft = (TextView) root.findViewById(R.id.leftBottom);
TextView botomRight = (TextView) root.findViewById(R.id.RightBottom);
topLeft.setText(TopLeft);
topRight.setText(TopRight);
bottomLeft.setText(LeftBottom);
botomRight.setText(RightBottom);
return root;
}
Create an VO for your items and add it in to the layout.
Like, layout.add(item)
See the following code if you're trying to add a child view (or multiple) to your root LinearLayout:
LinearLayout mRootLayout = (LinearLayout) findViewById(R.id.ll_root);
View mChildView = getLayoutInflater().inflate(R.layout.ll_child, mRootLayout,
false);
LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
mRootLayout.addView(mChildView, params);
TextView tvEventHour = (TextView) mChildView.findViewById(R.id.tv_event_hour);
TextView tvEventMessage = (TextView) mChildView.findViewById(R.id.tv_event_message);
tvEventHour.setText("10:30");
tvEventMessage.setText("Fugia corum...");
Note: If the list is about to get very long you should consider using a ListView with an Adapter since this is alot better performance-wise.
You can inflate from xml:
View placeHolderView = inflater.inflate(R.layout.view_header_placeholder, mListView);
What do you mean by "change the textviews inside per each item."?
If you need the textview inside the inflated layout try this:
TextView myTextView = (TextView)placeHolderView.findViewById(R.id.my_text_view);

ImageView is still null, after findbyView

Hey im trying to get a List working, in that case i have a xml defined item, which i inflate in a extended ArrayAdapter. But after i have inflated the xml, then when i try to grab the imageview, it returns null by findviewbyid...
Here is xml for the item:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="#+id/product_item_textview"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="if no image avail show this"
android:visibility="gone"/>
<ImageView
android:id="#+id/product_item_imageview"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:visibility="visible"
/>
</LinearLayout>
Method that instatiates the item:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
SimpleListItem item= items.get(position);
LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = vi.inflate(R.layout.product_item, null);
if(item.getPicture()!=null)
{
ImageView imgVw = (ImageView) findViewById(R.id.product_item_imageview);
String picturePath = item.getPicture();
Bitmap picture = ImageManager.get(getBaseContext(), picturePath);
imgVw.setImageBitmap(picture);
} else {
TextView txtVw = (TextView) findViewById(R.id.product_item_textview);
txtVw.setText(item.getText());
txtVw.setVisibility(View.VISIBLE);
}
return v;
}
Its a,
ImageView imgVw = (ImageView) v.findViewById(R.id.product_item_imageview);
also the same for TextView,
TextView txtVw = (TextView) v.findViewById(R.id.product_item_textview);
Use View v for getting ImageView and TextView from your inflated xml file.
//you are inflating layout in a view v so you need to get them by
ImageView imgVw = (ImageView)v. findViewById(R.id.product_item_imageview);
TextView txtVw = (TextView)v. findViewById(R.id.product_item_textview);

addfooterview cause exception

i inflate by this
linear = (LinearLayout) findViewById(R.id.layout_content);
linear.setVisibility(View.VISIBLE);
LayoutInflater liInflater = (LayoutInflater)this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
linear.addView(liInflater.inflate(R.layout.main_particularcategoryallnewslist, null));
linear.addView(liInflater.inflate(R.layout.main_particularcategoryallnewslistfv, null));
This is my listview
btnmore = (Button)findViewById(R.id.btn_more);
getListView().addFooterView(btnmore);
lv.setAdapter(adapter);
I want to inflate second time but failed.
However i can inflate firsttime which was
linear.addView(liInflater.inflate(R.layout.main_particularcategoryallnewslist, null));
What is the problem why i get this error?
java.lang.ClassCastException: android.widget.LinearLayout$LayoutParams cannot be cast to android.widget.AbsListView$LayoutParams
Try changing this:
linear.addView(liInflater.inflate(R.layout.main_particularcategoryallnewslist,
null));
To this:
linear.addView(liInflater.inflate(R.layout.main_particularcategoryallnewslist,
linear));
i think It's not because of the line you pointed out..
Did you call getLayoutParams() anywhere in your code?
Whenver you call getLayoutParams(), you show typecase to parent layoutparams.
Like, if your ListView's parent is LinearLayout then,
LinearLayout.LayoutParams params=(LinearLayout.LayoutParams) listView.getLayoutParams();
If your ListView's parent is RelativeLayout then,
RelativeLayout.LayoutParams params=(RelativeLayout.LayoutParams) listView.getLayoutParams();
I had similar situation - there was exception "java.lang.ClassCastException: android.widget.RelativeLayout$LayoutParams" on list_view.setAdapter();
I have managed to workaround this problem by using same layout for both footer and list items. The code below demonstrates how to use layout "listview_row" in footer and in items.
This is content of "listview_row.xml":
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/hs_line"
android:layout_alignParentLeft ="true"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<!-- TextView for list items -->
<TextView android:id="#+id/hs_line_textview"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:layout_alignParentLeft="true"
/>
<!-- Button for footer -->
<Button android:id="#+id/hs_line_footer_action"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:visibility="gone"
android:layout_alignParentLeft="true"
/>
</RelativeLayout>
Footer is initialized in such way:
View v = View.inflate(pager.Activity, R.layout.listview_row, null);
View footer = (View) v.findViewById(R.id.listview_line);
//footer doesn't use TextView, it uses Button only. So, we hide TextView.
footer.findViewById(R.id.hs_line_textview).setVisibility(View.GONE);
footer.findViewById(R.id.hs_line_footer_action).setVisibility(View.VISIBLE)
...
list_view.addFooterView(footer);
MyAdapter<Item> adapter = new MyAdapter(context, getListItems());
list_view.setAdapter(adapter);
Adapter:
public class MyAdapter<T> extends ArrayAdapter<T> {
private final ArrayList<T> _List;
private final LayoutInflater _Inflater;
public MyAdapter(Context context, ArrayList<T> srcList) {
super(context, 0, srcList);
_Inflater = LayoutInflater.from(context);
_List = srcList;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = _Inflater.inflate(R.layout.listview_row, null);
holder = new ViewHolder();
//item doesn't use Button, it uses TextView only
//Button is hidden by default (see xml)
holder.TextView = (TextView) convertView.findViewById(R.id.hs_line_textview);
} else {
holder = (ViewHolder) convertView.getTag();
}
//item initialization
.....
}
It's not ideal solution - only workaround, of course.

Categories

Resources