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.
Related
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.
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've got an app which got some data (titles of youtube videos) and displayed them in the TextViews which in the items in RecyclerView. But some of TextViews are not displayed, but data is loaded correctly.
On my phone don't displayed only few elements of list, on my old tabled - almost all elements are not displayed.
I do some experiments and learned that strings longer then some value are not displayed.
List item
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_margin="1dp"
android:descendantFocusability="blocksDescendants"
android:orientation="vertical"
android:padding="3dp"
android:background="#color/colorAccent">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/galley_photo_item_image"
android:layout_width="120dp"
android:layout_height="120dp"/>
<CheckBox
android:id="#+id/galley_photo_item_checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:buttonTint="#color/colorPrimary"
android:visibility="invisible"/>
</FrameLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="WTF"
android:minLines="3"
android:maxLines="3"
android:background="#color/colorPrimary"
android:id="#+id/image_name_text"/>
</LinearLayout>
My Adapter
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int i)
{
View convertView = inflater.inflate(R.layout.gallery_photo_item,parent,false);
ViewHolder view_holder = new ViewHolder(convertView);
//view_holder.Position = i;
//Event handling
view_holder.CheckBox.setOnClickListener(this);
view_holder.View.setOnClickListener(this);
convertView.setTag(view_holder);
//checkBox.setTag(position);
return view_holder;
}
#Override
public void onBindViewHolder(ViewHolder view_holder, int position)
{
//Toggle checkbox on DELETE MODE
if(is_checking) {
view_holder.CheckBox.setVisibility(View.VISIBLE);
view_holder.CheckBox.setChecked(checked[position]);
}
else
view_holder.CheckBox.setVisibility(View.INVISIBLE);
//view.setTag(position);
view_holder.CheckBox.setTag(position);
view_holder.Position=position;
//Display image
//String uri = Uri.fromFile(thumbs[position]).toString();
String uri = thumbs_fnames[position];
Glide.with(context)
.load(uri)
.centerCrop()
.into(view_holder.ImageView);
//Добавляем подписи (если есть)
if((thumbs_descriptions!=null))//&&(thumbs_descriptions.length==thumbs_fnames.length))
{
String text = thumbs_descriptions[position];
Log.d("ImageListAdapter",position +": "+text+"|");
view_holder.Description.setText(text);
}
else
Log.d("ImageListAdapter",position + ": nothing");
if(position== markred_id)
view_holder.View.setBackgroundResource(R.color.colorPrimary);
else
view_holder.View.setBackgroundResource(R.color.transparent);
}
And the last strange thing. When I set the text manually:
text = "Some long-long text bla-bla-bla ... ... ... ...;
it works correctly.
What the strange problem?
I did it. The problew was that FrameLayout has width and height mathc_parent instend wrap_content.
Correct XML
<?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"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_margin="1dp"
android:descendantFocusability="blocksDescendants"
android:orientation="vertical"
android:padding="3dp">
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/galley_photo_item_image"
android:layout_width="120dp"
android:layout_height="120dp"/>
<CheckBox
android:id="#+id/galley_photo_item_checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:buttonTint="#color/colorPrimary"
android:visibility="invisible"/>
</FrameLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minLines="3"
android:maxLines="3"
android:id="#+id/image_name_text"/>
Diff: https://www.diffchecker.com/qe8pcozv
You can also see difference in TextView height, but it doesn't metter, It works in both situations.
I want to show a notification counter like this:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:gravity="center"
android:padding="#dimen/_5sdp"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:alpha=".5"
android:id="#+id/gvIcon"
android:src="#drawable/ic_person_reading"
android:scaleType="centerCrop"
android:layout_width="#dimen/_70sdp"
android:layout_height="#dimen/_70sdp" />
<LinearLayout
android:id="#+id/llTexts"
android:gravity="center_horizontal"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
style="#style/gridItemsText"
android:id="#+id/gvText"
android:text="Guten Morgen"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/partNoticeTooltip"
android:orientation="vertical"
android:background="#drawable/bg_tooltip_red"
android:layout_width="#dimen/tooltipWH"
android:layout_height="#dimen/tooltipWH">
<TextView
android:id="#+id/tvCounter"
android:text="4"
android:textColor="#color/white"
android:textSize="#dimen/h6"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
Which has an output like this:
This is my expectation, but with dynamic way. So I wrote this in the setOnItemClickListener of my GridView:
View tooltip = context.getLayoutInflater().inflate(R.layout.part_tooltip, null);
TextView tvCounter = (TextView) tooltip.findViewById(R.id.tvCounter);
tvCounter.setText("" + counter);
LinearLayout llText = (LinearLayout) view.findViewById(R.id.llTexts);
llText.addView(tooltip);
the part_tooltip has exactly the same code but with another layout. And here is the output:
The red layout does not being displayed with full width. What am I missing?
You need to use a global layout listener and also the view tree observer:
ViewTreeObserver mVTO = parentLayoutOfTheViewAddedDynamically.getViewTreeObserver();
mVTO.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
if(viewAddedDynamically != null){
int viewWidth = viewAddedDynamically.getWidth();
// any operation based on viewWidth is to be done here
}
}
});
As I'm new to Android, I'm struggling to design a custom layout which is going to be my listview row. I like my list view row should contain title description, details and footer. My listview row hold data like the image I attached. Please see the attached image
You must need to create your_layout_row.xml first
<?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="60dp"
android:orientation="horizontal"
android:layout_margin="14dp"
>
<LinearLayout
android:layout_width="60dp"
android:layout_height="60dp"
>
<ImageView
android:id="#+id/imageView"
android:layout_width="wrap_content"
android:paddingLeft="10dp"
android:layout_height="60dp"
/>
</LinearLayout>
<TextView
android:gravity="center_vertical"
android:paddingBottom="10dp"
android:paddingRight="5dp"
android:id="#+id/textView"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_gravity="center_vertical"
android:layout_marginLeft="20dp"
android:text="TextView"
android:textStyle="normal|italic"
android:textSize="17dp" />
</LinearLayout>
now here you have your listview layout.
<?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="#color/TaskList_layout_background_color"
>
<ListView
android:id="#+id/lv_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp"
android:dividerHeight="10dp"
android:paddingBottom="5dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="5dp" >
</ListView>
</RelativeLayout>
now create your class Model
for example :
class ModelClass
{
String text;
public ModelClass(String _text)
{
text = _text;
}
public String getText()
{
return this.text;
}
}
now create your custom adapter class
public class CustomAdapter extends ArrayAdapter<ModelClass> {
// declaring our ArrayList of items
private ArrayList<ModelClass> objects;
/* here we must override the constructor for ArrayAdapter
* the only variable we care about now is ArrayList<Item> objects,
* because it is the list of objects we want to display.
*/
public CustomAdapter(Context context, int textViewResourceId, ArrayList<ModelClass> objects) {
super(context, textViewResourceId, objects);
this.objects = objects;
}
/*
* we are overriding the getView method here - this is what defines how each
* list item will look.
*/
#Override
public View getView(int position, View convertView, ViewGroup parent){
// assign the view we are converting to a local variable
View v = convertView;
// first check to see if the view is null. if so, we have to inflate it.
// to inflate it basically means to render, or show, the view.
if (v == null) {
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.your_layout_row null);
}
/*
* Recall that the variable position is sent in as an argument to this method.
* The variable simply refers to the position of the current object in the list. (The ArrayAdapter
* iterates through the list we sent it)
*
* Therefore, i refers to the current Item object.
*/
ModelClass i = objects.get(position);
if (i != null) {
// This is how you obtain a reference to the TextViews.
// These TextViews are created in the XML files we defined.
TextView tt = (TextView) v.findViewById(R.id.textView);
// check to see if each individual textview is null.
// if not, assign some text!
if (tt != null){
tt.setText( objects.get(position).getText());
}
}
// the view must be returned to our activity
return v;
}
}
now in your main activity set your listview adapter to this customAdapter.
ArrayList<MyModel> myList = new new ArrayList<MyModel>();
myList.add("1");
myList.add("2");
myList.add("3");
myList.add("4");
ListView myListView = (ListView)findViewById(R.id.lv_list);
CustomAdapter adapter= new CustomAdapter(acitivity, 0, myList);
myListView.setAdapter(adapter);
In this case, you have to custom adapter.
Actually Relative is more suitable for designs. But now I'll write with LinearLayout to be easy.
here is the custom layout for listview item...
<?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:id="#+id/title"
android:layout_width="match_parent"
android:layout_height="30dp"
android:text="Title"
android:background="#android:color/holo_red_light"
android:gravity="center"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="60dp"
android:layout_weight="1"
android:gravity="center"
android:background="#android:color/holo_green_light"
android:text="DESC"/>
<TextView
android:layout_width="0dp"
android:layout_height="60dp"
android:layout_weight="1"
android:gravity="center"
android:background="#android:color/holo_blue_light"
android:text="Other Detais"/>
</LinearLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="30dp"
android:text="Footer"
android:background="#android:color/holo_red_light"
android:gravity="center"/>
</LinearLayout>
copy and modify above answer by Hein Htet Aung
<TextView
android:id="#+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:text="Title"
android:background="#android:color/holo_red_light"
android:gravity="center"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:padding="20dp"
android:background="#android:color/holo_green_light"
android:text="DESC"/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:padding="20dp"
android:layout_weight="1"
android:gravity="center"
android:background="#android:color/holo_blue_light"
android:text="Other Detais"/>
</LinearLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="15dp"
android:text="Footer"
android:background="#android:color/holo_red_light"
android:gravity="center"/>