How to build a complex layout in android with multiple watchlists

We are working on an application with several components that we want to integrate into the detailed view of the message (see the layout.) Each of the parts is extensible (usually using an ajax call), and the entire screen scrolls to see all the content.

listview mockup

We are not sure of the best way to solve this problem, because, according to Google, view lists should not be entered in scrollviews. It seems there are people who do this anyway, like in How can I put a ListView in a ScrollView without smoothing it? .

In general, the amount of content that is in the message is small enough to be inflated immediately, but you can receive messages with 100 + photos or more than 300 comments in which a memory problem may occur.

My question is the best, if not official, way to create such a layout. I am interested in hearing recommendations for the entire layout structure, so I understand how more static content, such as the title, plays with photos or comments.

I would like to optimize the performance / ease of implementation for small messages (several photos, 20-50 comments), but we should be able to process large messages without crashing the application.

+7
android android-layout listview
source share
4 answers

At first I thought it was a complicated layout for tablets, but if it's just 1 list, it can be implemented using a custom list adapter.

Present this layout as a single list with different views. Thus, the message heading is an element of the type 1 list, the type of the photo is type 3, the button is type 4. Here is your layout with position positions marked with red numbers and view types marked with blue text.

OP layout with marked item positions

You must create model classes for each element with the viewType property, so for 11 types of view there will be 11 classes (or a base class and several derived classes). Then add these models in the proper order to your adapter as follows:

  this.add(new ListItemModelBase(ListItemViewTypes.POST_TITLE)); this.add(new PhotoViewItemModel("image1.jpg", "Image 1")); this.add(new PhotoViewItemModel("image2.jpg", "Image 2")); this.add(new PhotoViewItemModel("image3.jpg", "Image 3")); this.add(new ListItemModelBase(ListItemViewTypes.SEE_MORE_PHOTOS_BUTTON)); // other models 

Then you can update / add / remove list items by changing models. For example, if you click the View More Text button, call the following function:

 private void onSeeMoreTextButtonClicked(ListItemModelBase item){ item.setViewType(ListItemViewTypes.POST_TITLE_EXPANDED); this.notifyDataSetChanged(); } 

If you click the "View more photos" button, call this function:

 private void onSeeMorePhotosButtonClicked(ListItemModelBase item){ int index = this.getPosition(item); this.remove(item); this.insert(new PhotoViewItemModel("image4.jpg", "Image 4"), index); this.insert(new PhotoViewItemModel("image5.jpg", "Image 5"), index + 1); this.insert(new PhotoViewItemModel("image6.jpg", "Image 6"), index + 2); } 

I think the idea is clear.

Here is a complete example for four view types:

 public class ListItemViewTypes { public static final int VIEW_TYPES_COUNT = 4; // Must start from 0 public static final int POST_TITLE = 0; public static final int POST_TITLE_EXPANDED = 1; public static final int PHOTO_VIEW = 2; public static final int SEE_MORE_PHOTOS_BUTTON = 3; } public class ListItemModelBase { private int mViewType; public ListItemModelBase(int viewType){ mViewType = viewType; } public int getViewType() { return mViewType; } public void setViewType(int viewType) { mViewType = viewType; } } public class PhotoViewItemModel extends ListItemModelBase { private final String mUrl; private final String mDescription; public PhotoViewItemModel(String url, String description) { super(ListItemViewTypes.PHOTO_VIEW); mUrl = url; mDescription = description; } public String getUrl() { return mUrl; } public String getDescription() { return mDescription; } } public class TestListAdapter extends ArrayAdapter<ListItemModelBase> { private final LayoutInflater mInflater; public TestListAdapter(Context context) { super(context, -1); mInflater = LayoutInflater.from(context); this.add(new ListItemModelBase(ListItemViewTypes.POST_TITLE)); this.add(new PhotoViewItemModel("image1.jpg", "Image 1")); this.add(new PhotoViewItemModel("image2.jpg", "Image 2")); this.add(new PhotoViewItemModel("image3.jpg", "Image 3")); this.add(new ListItemModelBase(ListItemViewTypes.SEE_MORE_PHOTOS_BUTTON)); } @Override public int getViewTypeCount() { return ListItemViewTypes.VIEW_TYPES_COUNT; } @Override public int getItemViewType(int position) { // important method so that convertView has a correct type return this.getItem(position).getViewType(); } @Override public boolean isEnabled(int position) { // enable context menu for photo views, comments and related posts // or always return false if context menu is not needed at all if (this.getItem(position).getViewType() == ListItemViewTypes.PHOTO_VIEW) { return true; } return false; } @Override public View getView(int position, View convertView, ViewGroup parent) { final ListItemModelBase item = this.getItem(position); int viewType = item.getViewType(); if (convertView == null) { // different layouts for different `viewType` int layoutId = -1; if (viewType == ListItemViewTypes.POST_TITLE) { layoutId = R.layout.post_title; } else if (viewType == ListItemViewTypes.POST_TITLE_EXPANDED) { layoutId = R.layout.post_title_expanded; } else if (viewType == ListItemViewTypes.PHOTO_VIEW) { layoutId = R.layout.photo_view; } else if (viewType == ListItemViewTypes.SEE_MORE_PHOTOS_BUTTON) { layoutId = R.layout.more_photos_button; } convertView = this.mInflater.inflate(layoutId, null); } // update the current view based on data from the current model if (viewType == ListItemViewTypes.POST_TITLE) { Button seeMoreTextButton = (Button)convertView.findViewById(R.id.button_see_more_text); seeMoreTextButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { onSeeMoreTextButtonClicked(item); } }); } else if (viewType == ListItemViewTypes.SEE_MORE_PHOTOS_BUTTON) { Button seeMorePhotosButton = (Button)convertView.findViewById(R.id.button_see_more_photos); seeMorePhotosButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { onSeeMorePhotosButtonClicked(item); } }); } else if (viewType == ListItemViewTypes.PHOTO_VIEW){ PhotoViewItemModel photoViewItem = (PhotoViewItemModel)item; TextView photoDescriptionText = (TextView)convertView.findViewById(R.id.photo_view_text); photoDescriptionText.setText(photoViewItem.getDescription()); } return convertView; } private void onSeeMoreTextButtonClicked(ListItemModelBase item){ item.setViewType(ListItemViewTypes.POST_TITLE_EXPANDED); this.notifyDataSetChanged(); } private void onSeeMorePhotosButtonClicked(ListItemModelBase item){ int index = this.getPosition(item); this.remove(item); this.insert(new PhotoViewItemModel("image4.jpg", "Image 4"), index); this.insert(new PhotoViewItemModel("image5.jpg", "Image 5"), index + 1); this.insert(new PhotoViewItemModel("image6.jpg", "Image 6"), index + 2); } } public class MainActivity extends ListActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //setContentView(R.layout.activity_main); this.getListView().setChoiceMode(ListView.CHOICE_MODE_NONE); this.getListView().setDivider(null); TestListAdapter adapter = new TestListAdapter(this.getApplicationContext()); this.getListView().setAdapter(adapter); } } 
+7
source share

Looking at the requirement that you have, I can think of these three possible solutions on my head:

I personally see that you are using a combination of 1 and 3 to solve your current problem.

I highly recommend using listview on a list or list in scroll. They will have performance problems and other things that you really don't want to delve into. Hope this helps.

+3
source share

A graphic layout can easily do the trick. first vertical, then relative layout with widgets scroll property.

0
source share

custom list with various adapters will solve your problem

0
source share

All Articles