Good day! How can I add TextView automatically base on table rows and display the row data in the generated TextView, or is there another way to accomplish this.
Row 1
PA : Savings Account // Col 1
2015-08-17 // Col 2
483.67 // Col 3
483.67 // Col 4
Row 2
PA : Savings - Cash Bond // Col 1
2015-08-28 // Col 2
10129.43 // Col 3
10129.43 // Col 4
this is my current code
private TextView textView_SL_Desc;
private TextView textView_SL_Bal;
textView_SL_Desc = (TextView) findViewById(R.id.sl_desc);
textView_SL_Bal = (TextView) findViewById(R.id.actual_balance);
// Fetching USER sl details from SQlite
HashMap<String, String> sl_summ = db.getUserSLDTL();
String sl_desc = sl_summ.get("sl_desc");
String actual_balance = sl_summ.get("actual_balance");
//Set text to text view
textView_SL_Desc.setText(sl_desc);
textView_SL_Bal.setText(actual_balance);
My XML
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:gravity="center"
android:orientation="vertical" >
<TextView
android:id="#+id/sl_desc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="13sp" />
<TextView
android:id="#+id/actual_balance"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="13sp" />
</LinearLayout>
RecyclerView will solve your problem for dynamically creating a list of views (in your case, your XML file) in an efficient way.
How to use RecyclerView:
Create a ViewHolder class to hold your TextView widgets
public class RowViewHolder extends RecyclerView.ViewHolder {
public final TextView textView_SL_Desc;
public final TextView textView_SL_Bal;
public RowViewHolder(View itemView) {
super(itemView);
textView_SL_Desc = (TextView) itemView.findViewById(R.id.sl_desc);
textView_SL_Bal = (TextView) itemView.findViewById(R.id.actual_balance);
}
}
Create a RecylerView.Adapter class to bind your data with your UI (something similar to two-way binding model if you are familiar with AngularJS)
public class RecyclerAdapter RecyclerView.Adapter<RowViewHolder> {
private List<HashMap<String, String>> sl_summList;
public RecyclerAdapter(List<HashMap<String, String>> sl_sumnList) {
this.sl_sumnList = sl_sumnList;
}
// This is the code where RecyclerView knows how to create views from your ViewHolder class (in this case, RowViewHolder)
#Override
public RowViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = (LayoutInflater) parent.getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.your_xml_layout, parent, false);
return new RowViewHolder(view);
}
// This is the code where RecyclerView populates data (binds data to UI)
#Override
public void onBindViewHolder(RowViewHolder holder, int position) {
// This is the code where you get data based on position of the table. I cannot write specific code because I don't know how your hashmap looks like
String sl_summ = this.sl_sumnList.get(position);
holder.textView_SL_Desc.setText(sl_summ.get("sl_desc"));
holder.textView_SL_Bal.setText(sl_summ.get("actual_balance"));
}
// How RecyclerView knows how many items are in the list
#Override
public int getItemCount() {
return sl_sumnList.size();
}
}
Hooks RecyclerView with your RecylerView.Adapter class
mRecyclerView = (RecyclerView) findViewById(R.id.your_recycler_view_id);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(layoutManager);
List<HashMap<String,String> dbRowList = db.get_all_rows(); // get all items from your database)
mRecyclerAdapter = new RecyclerAdapter(dbRowList);
mRecyclerView.setAdapter(mRecyclerAdapter); // finally hooks up RecyclerView.Adapter with RecyclerView.
Here is an official tutorial of ReyclerView, https://developer.android.com/training/material/lists-cards.html.
You should explore ListView and ArrayAdapter for displaying dynamic list of data (in your case table rows).
You can have your own designed ListView to display data in specific manner.
there are several ways to accomplish this.
I prefer to add Linearlayouts dynamically. It´s easy and you can Display nearly every data you want.
First: Take your .xml file and name it into "show_data_item"
<?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="100sp"
android:weightSum="2"
android:id="#+id/show_data_item">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="2sp"
android:background="#000000"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0sp"
android:layout_weight="1"
android:weightSum="2">
<LinearLayout
android:layout_width="2sp"
android:layout_height="match_parent"
android:background="#000000"/>
<TextView
android:id="#+id/col1"
android:layout_width="wrap_content"
android:text="Display Data Col1"
android:layout_weight="1"
android:layout_height="wrap_content" />
<LinearLayout
android:layout_width="2sp"
android:layout_height="match_parent"
android:background="#000000"/>
<TextView
android:id="#+id/col2"
android:text="Display Data Col2"
android:layout_weight="1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<LinearLayout
android:layout_width="2sp"
android:layout_height="match_parent"
android:background="#000000"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="2sp"
android:background="#000000"/>
<LinearLayout
android:layout_height="0sp"
android:layout_weight="1"
android:weightSum="2"
android:layout_width="match_parent">
<LinearLayout
android:layout_width="2sp"
android:layout_height="match_parent"
android:background="#000000"/>
<TextView
android:id="#+id/col3"
android:layout_width="wrap_content"
android:text="Display Data Col3"
android:layout_weight="1"
android:layout_height="wrap_content" />
<LinearLayout
android:layout_width="2sp"
android:layout_height="match_parent"
android:background="#000000"/>
<TextView
android:id="#+id/col4"
android:layout_width="wrap_content"
android:text="Display Data Col4"
android:layout_weight="1"
android:layout_height="wrap_content" />
<LinearLayout
android:layout_width="2sp"
android:layout_height="match_parent"
android:background="#000000"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="2sp"
android:background="#000000"/>
</LinearLayout>
Step 2: Create an xml Layout for your activity and don´t forget to add it to "manifest.xml", like this (made it with a scrollview so that you have unlimited space) :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="vertical">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="#+id/displaydata"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent"></LinearLayout>
</ScrollView>
</LinearLayout>
Step 3: Create an class in java which fill´s the textviews with your col1-4, and add this to your "id/displaydata" with the funktion:
myView.addview(show_data_item); //myView is an Object of LinearLayout and show_data_item is also a object of LinearLayout.
This is how you do it.
You can also use a List/RecylerView and add your data with an Adapter. You still need an Layout for your show_data_item.
Here is a code example for this
All ways leads to rome, i guess.
Related
I am pretty new in Android.
I have some problems to create a dynamic LinearLayout programmatically.
I actually have some information in ArrayLists that I need to display. The problem is that I don't know how many items are in the ArrayList, so I need to create the same layout (LinearLayoutChild) for every item in the ArrayList.
For example, I have created this (in this case, let's say the ArrayLists have 2 items each)
ArrayList<String> alistA = new ArrayList<String>();
ArrayList<String> alistB = new ArrayList<String>();
ArrayList<String> alistC = new ArrayList<String>();
ArrayList<String> alistD = new ArrayList<String>();
ArrayList<String> alistE = new ArrayList<String>();
alistA.add(0, "TextA1");
alistA.add(1, "TextA2");
alistB.add(0, "TextB1");
alistB.add(1, "TextB2");
alistC.add(0, "TextC1");
alistC.add(1, "TextC2");
alistD.add(0, "TextD1");
alistD.add(1, "TextD2");
alistE.add(0, "TextE1");
alistE.add(1, "TextE2");
int NumberArray = 2;
for(int i = 0; i<NumberArray;i++){
// How can i do this?
}
I want to display it like :
alistA[0] -> Tv1
alistB[0] -> Tv2
and so on...
alistA[[1]] -> Tv1 (newly created)
alistB[[1]] -> Tv2 (newly created)
...
My XML file :
<?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="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.murat.testlol.MainActivity"
android:id="#+id/LinearLayout1"
android:orientation="vertical">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/Et1"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/Btn1"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:weightSum="12"
android:orientation="horizontal"
android:id="#+id/LinearLayoutChild">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="4"
android:orientation="vertical"
android:id="#+id/Ll1">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/Tv1"
android:gravity="center"
android:text="TextView1"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="TextView2"
android:id="#+id/Tv2"
android:gravity="center"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="4"
android:orientation="vertical"
android:id="#+id/Ll2">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/Tv3"
android:gravity="center"
android:text="TextView3"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:id="#+id/Tv4"
android:text="TextView4"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="4"
android:orientation="vertical"
android:id="#+id/Ll3">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/Tv5"
android:gravity="center"
android:text="TextView5"/>
</LinearLayout>
</LinearLayout>
The EditText and button need to stay at the same place.
Thank you.
Sounds like a good use case for Android's ListView. From Google's documentation:
ListView is a view group that displays a list of scrollable items. The list items are automatically inserted to the list using an Adapter that pulls content from a source such as an array or database query and converts each item result into a view that's placed into the list.
To go this route, update main.xml to include a ListView element -- and move the LinearLayoutChild into its own XML file.
main.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="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.murat.testlol.MainActivity"
android:id="#+id/LinearLayout1"
android:orientation="vertical">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/Et1"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/Btn1"/>
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/list"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
generic_linear_layout_child.xml:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="4"
android:orientation="vertical"
android:id="#+id/linear_layout_child">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/Tv1"
android:gravity="center"
android:text="TextView1"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="TextView2"
android:id="#+id/Tv2"
android:gravity="center"/>
</LinearLayout>
Then, create an adapter to bind the data in your array to the appropriate UI elements. Here's a SO post on how to create a custom adapter: Custom Adapter for List View
You need to create the linearlayouts and textviews dynamically, using routines like this:
public TextView makeTextView (String text)
{
TextView tv = new TextView (context)
tv.setText (text) ;
// customise the layout of the text here, eg...
tv.setTextColor(Color.RED) ;
return tv;
}
public LinearLayout makeHorizLayout ()
{
LinearLayout ll = new LinearLayout (context);
ll.setOrientation(LinearLayout.HORIZONTAL);
ll.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
return ll;
}
After you have loaded the schema, you find the view that you want to insert the linearLayouts into like this:
View mainView = findViewById (R.id.LinearLayout1);
You then add a linearlayout to a view like this:
LinearLayout ll = makeHorizlayout ();
mainView.add(ll);
Then you add textviews to the LinearLayout like this:
TextView tv = makeTextView ("whatever text");
ll.addView (tv);
Do the following. Get your data and fill a linearLayout container during runtime after you have retrieved / created your data. Here is an example for creating the views.
private LinearLayout container;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
container = new LinearLayout(this);
container.setOrientation(LinearLayout.VERTICAL)
// + other layout stuff / better inflate this from xml
// Get data and call createLayout with the data
}
createLayout(List<List<String>> lists) {
for (List<String> list : lists) {
LinearLayout linearLayout = new LinearLayout(this);
linearLayout.setOrientation(LinearLayout.HORIZONTAL);
// + other layout stuff / better inflate this from xml
for (String string : list) {
TextView textView = new AppCompatTextView(this);
textView.setText(string);
linearLayout.addView(textView);
}
container.addView(linearLayout);
}
}
I am trying to map a List<List<Object>> to a RecyclerView in Android, but the result is totally messed up.
For example, I have a list of list like this (just for explaining, not my real case):
List<List<String>> list = {{a, b, c}, {d, e}, {f, g, h, i}};
the Recyclerview should display like (first row contains three subrows, second has two and the last on has four):
|----a-----|
|----b-----|
|----c-----|
|=======|
|----d-----|
|----e-----|
|=======|
|----f-----|
|----g-----|
|----h-----|
|----i-----|
but the result is not exactly like the above order. some element is duplicated and some disappears. for example:
|----d-----|
|----e-----|
|----c-----|
|=======|
|----d-----|
|----e-----|
|=======|
|----f-----|
|----a-----|
Here is a piece of my code:
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
List<Event> list = eventList.get(position);
if (holder.rows < list.size()) {
holder.rowViewGroup.removeAllViews();
holder.rows = 0;
ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
TextView startView = new TextView(context);
startView.setLayoutParams(layoutParams);
Event headEvent = list.get(0);
Calendar startCal = headEvent.getStartCal();
startView.setText(String.format("%tD", startCal));
holder.rowViewGroup.addView(startView);
for (final Event event : list) {
View element = LayoutInflater.from(context).inflate(R.layout.element, null);
//start time view
TextView startTimeView = (TextView)element.findViewById(R.id.eventStartTimeInElement);
Calendar startTimeCal = event.getStartCal();
startTimeView.setText(String.format("%tl:%tM %tp", startTimeCal, startTimeCal, startTimeCal));
//end date time view
TextView endView = (TextView)element.findViewById(R.id.eventEndTimeInElement);
Calendar endCal = event.getEndCal();
endView.setText(String.format("%tD %tl:%tM %tp", endCal, endCal, endCal, endCal));
//title view
TextView title = (TextView)element.findViewById(R.id.eventTitleInElement);
title.setText(event.getTitle());
//member name
Drawable divider = context.getResources().getDrawable(R.drawable.divider);
ImageView dividerView = new ImageView(context);
dividerView.setImageDrawable(divider);
holder.rowViewGroup.addView(dividerView);
holder.rowViewGroup.addView(element);
holder.rows++;
}
}
}
Here is my row.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/recycleViewRow">
<android.support.v7.widget.CardView
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="#+id/cardView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
card_view:cardCornerRadius="0dp"
card_view:cardElevation="2sp"
card_view:cardUseCompatPadding="true"
>
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/rowView"
android:paddingLeft="20dp"
android:paddingRight="20dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/eventStartTimeInRow"
/>
</LinearLayout>
</android.support.v7.widget.CardView>
and element.xml(which is contained by row.xml):
<?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="wrap_content">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="Small Text"
android:id="#+id/eventStartTimeInElement"
android:layout_weight="2" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="Small Text"
android:id="#+id/eventEndTimeInElement"
android:gravity="end"
android:layout_weight="1"/>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="left">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Medium Text"
android:id="#+id/eventTitleInElement"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="right">
<android.support.v7.widget.CardView
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
card_view:cardCornerRadius="2dp"
card_view:cardElevation="2sp"
card_view:cardUseCompatPadding="true">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="Small Text"
android:id="#+id/memberNameInElement"
android:gravity="end"
/>
</android.support.v7.widget.CardView>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>
And I know this is not a really good idea to implement this, so could anybody please tell me a better way to implement this? Thanks...
I think your best bet is to flatten your list of lists into one list.
This is just for purposes of the ListView. Your adapter will act as though the lists have all been strung into one long list.
Start by creating a single-list index for all the items of your nested lists.
For example:
List<List<String>> listOfLists = ... // your original data
List<String> listForView = new ArrayList<String>();
for (List<String> innerList : listOfLists) {
for (String str : innerList) {
listForView.add(str);
}
listForView.add("---"); // e.g. marker value for divider
}
Now in your adapter's getItem() need only return listForView.get(position).
Anytime your nested list structure changes, you redo this flattening operation and call notifyDataSetChanged().
Things get a little trickier if — given the position — you have to figure out which list an item is in, but you could always index the inner lists in a similar fashion.
Trying to replace the ListView with RecyclerView.
Not sure if someone also having problem to use RecyclerView. I noticed without changing the view item layout, using RecyclerView the scrolling is not as smooth as when using ListView, and for my view item layout only GridLayoutManager works.
Any suggestion? thanks!
The view item layout is not changed and it has been working fine with ListView (has > 1000 data).
With ListView:
<ListView
android:id="#+id/list_view"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</ListView>
public class UsingListViewAdapter extends BaseAdapter;
UsingListViewAdapter mAdaptor new UsingListViewAdapter(null, mSelectListener);
mListView = (ListView) view.findViewById(R.id.list_view);
mListView.setAdapter(mAdaptor);
with RecyclerView:
<android.support.v7.widget.RecyclerView
android:id="#+id/list_view"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent”/>
public class UsingRecyclerViewAdapter extends RecyclerView.Adapter< UsingRecyclerViewAdapter.RowViewHolder>
implements View.OnClickListener, View.OnLongClickListener;
UsingRecyclerViewAdapter mAdaptor new UsingRecyclerViewAdapter(null, mSelectListener)
mRecyclerView = (RecyclerView) view.findViewById(R.id.list_view);
mRecyclerView.setHasFixedSize(true);
mLayoutManager = new GridLayoutManager(getActivity(), 1);
//mLayoutManager = new LinearLayoutManager(getActivity());
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setAdapter(mAdaptor);
The view item used in the Adapters of ListView and RecyclerView are same layout, which one row has two elements side by side using layout_width=“0dp"/layout_weight=“1” to stretch to fill the row.
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="top" >
<LinearLayout
android:id="#+id/row"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="6dp"
android:orientation="horizontal"
android:visibility="gone"
>
<include
android:id="#+id/row_cell_one"
layout="#layout/cell_layout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
/>
<include
android:id="#+id/row_cell_two"
layout="#layout/cell_layout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"/>
</LinearLayout>
The cell_layout is like:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<RelativeLayout
android:id="#+id/img_container"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<ImageView
android:id="#+id/img"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="centerCrop"
android:src="#drawable/dumy_img" />
<ImageView
android:id="#+id/overlay_img"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_centerInParent="true"
android:background="#drawable/box_border"
android:scaleType="center"
android:src="#drawable/overlay_image"
android:tint="#color/dark_pink"
android:visibility="gone" />
</RelativeLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="#dimen/padding_top"
android:paddingBottom="#dimen/padding_bottom"
android:orientation="vertical" >
<TextView
android:id="#+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/left"
android:layout_marginRight="#dimen/right"
android:ellipsize="end"
android:textSize="#dimen/text_size"
android:gravity="left"
android:singleLine="true"
android:textColor="#color/black"/>
<TextView
android:id="#+id/text_2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/left"
android:layout_marginRight="#dimen/right"
android:ellipsize="end"
android:textSize="#dimen/text_size"
android:gravity="left"
android:singleLine="true"
android:textColor="#color/light_blue" />
</LinearLayout>
Both (using ListView or RecyclerView) have similar Adapter to update the View,
except in RecyclerView implemented
public RowViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
public void onBindViewHolder(RowViewHolder holder, int position)
public int getItemCount()
First notice is the the scrolling of using ListView is much much smoother than using the RecyclerView.
If use LinearLayoutManager, the items displayed in the row are messed up. The two items do not occupy full width of the display, and the element supposed to be overlay on top of other element (e.g img.top == overlay_img.top) is placed below (e.g. overlay_img.top == img.top + img.height), and with same height of white space below the overlay_img.
Only after changed to use mLayoutManager = new GridLayoutManager(getActivity(), 1); then the row is properly displayed.
with RecyclerView (using LinearLayoutManager) it is displayed as:
+---------------------+
(cell | (cell
one) | two)
+---------------------+
With ListView and RecyclerView (using GridLayoutManager) it is displayed as:
+---------------------+
(cell one) | (cell two)
+---------------------+
I am creating a Help page in which I have a set of questions and answers. These questions and answers have different styles. Here is the xml file, which describes the layout of a question & answer set:
<?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"
android:layout_gravity="center">
<TextView
android:text="#string/Help_first_question"
android:id="#+id/text1"
android:padding="5dip"
android:background="#e0f3ff"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<LinearLayout
android:id="#+id/panel1"
android:visibility="gone"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView
android:layout_margin="2dip"
android:text="#string/Help_first_answer"
android:padding="5dip"
android:background="#FFFFFF"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
</LinearLayout>
I want to display multiple questions and answers within a listView, whereby each row contains a set of the question and the answer. My listview looks like :
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/listview"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
</ListView>
so it will look like :
first row : Q
A
second row : Q
A
third row : Q
A
What is the best approach for achieving this?
create custom adapter and use the below layout to achieve your goal
<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="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
</LinearLayout>
You need to implement a custom ListAdapter implementing all of the abstract methods.
Let's create a QuestionAndAnswerListAdapter, which you can make your ListView by setting it up in onCreate:
public void onCreate(Bundle savedInstanceState) {
super(savedInstanceState);
setContentView(R.layout.listview);
QuestionsAndAnswersListAdapter adapter = new QuestionsAndAnswersListAdapter(data);
ListView listView = (ListView) findViewById(R.id.listview);
listView.setAdapter(adapter);
}
The adapter itself would look something like this:
public QuestionsAndAnswersListAdapter implements ListAdapter {
private QuestionAndAnswer[] data;
public QuestionsAndAnswersListAdapter(QuestionAndAnswer[] data) {
this.data = data;
}
public View getView(int position, View view, ViewGroup parent) {
if(view == null) {
//Only creates new view when recycling isn't possible
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.question_and_answer_list_item, null);
}
QuestionAndAnswer thisQA = data[position];
TextView questionView = (TextView) view.findViewById(R.id.text1);
questionView.setText(thisQA.question);
TextView answerView = (TextView) view.findViewById(R.id.answer);
answerView.setText(thisQA.answer);
return view;
}
// ...
}
getView is really the central method to get right. The rest of the methods you need to implement to live up to the ListAdapter interface are pretty straight-forward. Check the reference to see exactly what they are.
I am having problems with ListView on android. I have an Activity with an EditText view and a button. The idea is user should enter some info in the EditText field, touch the Search button which retrieves a list from a web service that it is displayed in the same activity below the EditText and the Button. Everything fine, I got the data from Internet but items weren't displaying. I was using the notifyDataSetChanged(). After a couple of hours with no success, I decided trying to put some items manually and it turns out that again nothing was displayed, hence I think I am doing something wrong when I am trying to set the listview and the adapter. So here is the code..
the xml of the activity activity_search.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp">
<EditText
android:id="#+id/edit_search"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="5"
android:inputType="text"
android:hint="Enter info"
android:ems="10" >
<requestFocus />
</EditText>
<Button
android:id="#+id/button_search"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#android:drawable/ic_menu_search"
android:contentDescription="Search"
android:ems="10" />
</LinearLayout>
<ListView
android:id="#+id/listview_items"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawSelectorOnTop="false" />
The XML of the item row.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_margin="5dp">
<TextView
android:id="#+id/row_code"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/Common_TextContent"
android:textAppearance="#android:style/TextAppearance.Holo.Medium" />
<TextView
android:id="#+id/row_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:text="#string/Common_TextContent"
android:textAppearance="#android:style/TextAppearance.Holo.Small" /></LinearLayout>
the custom Adapter:
public class ItemsListAdapter extends ArrayAdapter<ItemsList> {
private int[] colors = new int[] { 0x30ffffff, 0x30808080 };
public AssetListAdapter(Context context,
List<ItemsList> itemsList) {
super(context, 0, itemsList);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.row, null);
}
convertView.setBackgroundColor(colors[position % colors.length]);
TextView code = (TextView) convertView.findViewById(R.id.row_code);
code.setText(getItem(position).getCode());
TextView name = (TextView) convertView.findViewById(R.id.row_name);
name.setText(getItem(position).getName());
return convertView;
}
and the onCreate method on the Activity
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search);
_listView = (ListView) findViewById(R.id.listview_items);
_listItems = new ArrayList<ItemsList>();
_listItems.add(new ItemsList ("cosa1", "cosa1", "cosa1", "cosa1"));
_listItems.add(new ItemsList ("cosa2", "cosa2", "cosa2", "cosa2"));
_listItems.add(new ItemsList ("cosa3", "cosa3", "cosa3", "cosa3"));
_adapter = new ItemsListAdapter(this, _listItems);
_listView.setAdapter(_adapter);
}
The ItemsList is just an Object with 4 strings with all the getters implemented.
When I debug in the getView method of the Adapter, the view (convertView) is created and it has the right information. It is just that is not showing those in the screen. What am I doing wrong?
Thanks...
Your second LinearLayout has a height of match_parent. Try wrap_content instead.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp">