我的目标是创建一个应用程序来显示按天分组的数据列表。实际截图见下图。
为了实现这个设计,我使用了自定义数组列表适配器来实现这个设计。下面是我的 DiaryListAdapter
类文件public class DiaryListAdapter extends ArrayAdapter<Records> {
/**
* Adapter context
*/
Context mContext;
/**
* Adapter View layout
*/
int mLayoutResourceId;
int selectedItem = -1;
private Records _records;
public DiaryListAdapter(Context context, int layoutResourceId, ArrayList<Records> recordItems) {
super(context, layoutResourceId, recordItems);
this.mContext = context;
this.mLayoutResourceId = layoutResourceId;
}
private static class ViewHolder {
TextView diaryTime, diarySysDia, diaryPul, itemDate, itemToday;
LinearLayout llDiaryHead;
}
/**
* Returns the view for a specific item on the list
*/
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// Declare the new object
ViewHolder viewHolder;
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) mContext
.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.lv_diarycontent_adapter, null);
// Instantiate the object
viewHolder = new ViewHolder();
viewHolder.itemDate = (TextView) convertView.findViewById(R.id.itemDate);
viewHolder.itemToday = (TextView) convertView.findViewById(R.id.itemToday);
viewHolder.diaryTime = (TextView) convertView.findViewById(R.id.itemTime);
viewHolder.diarySysDia = (TextView) convertView.findViewById(R.id.itemSysDia);
viewHolder.diaryPul = (TextView) convertView.findViewById(R.id.itemPulse);
viewHolder.llDiaryHead = (LinearLayout) convertView.findViewById(R.id.ll_diaryhead);
convertView.setTag(R.id.TAG_DIARY_VIEWHOLDER_ID, viewHolder);
} else {
// Instantiate the new object
viewHolder = (ViewHolder) convertView.getTag(R.id.TAG_DIARY_VIEWHOLDER_ID);
}
// Declare the reminder object
_records = getItem(position);
if (_records.getIsDateHead()) {
// Hide the layout header
viewHolder.llDiaryHead.setVisibility(View.VISIBLE);
// Display the value on textview
viewHolder.itemDate.setText(FormatterMgr.DSPLY_DATE_LSTVIEW.format(_records.getRecordCreatedOn()));
// Display the value inside the content
viewHolder.diaryTime.setText(_records.getRecordCreatedOn().toString());
viewHolder.diarySysDia.setText(_records.getSys() + "/" + _records.getDia());
viewHolder.diaryPul.setText(Float.toString(_records.getHr()));
} else {
// Hide the layout header
viewHolder.llDiaryHead.setVisibility(View.GONE);
// Display the value inside the content
viewHolder.diaryTime.setText(_records.getRecordCreatedOn().toString());
viewHolder.diarySysDia.setText(_records.getSys() + "/" + _records.getDia());
viewHolder.diaryPul.setText(Float.toString(_records.getHr()));
}
convertView.setTag(R.id.TAG_DIARY_LIST_ID, _records);
return convertView;
}
public void setSelectedItem(int selectedItem) {
this.selectedItem = selectedItem;
}
下一节课是DiaryFragment。这是我编写要在页面内显示的 ListView 的 UI 代码隐藏文件。这是我在尝试显示 ListView 并相应地按天分组时遇到困难的代码。
public class DiaryFragment extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_DIARY = "diary";
private static final String ARG_PARAM2 = "param2";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
RecordsTableHelper rth;
HashSet<String> uniqueSet;
ArrayList<Records> mRecordsArrayList;
ListView mDiaryListView;
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* @param param1 Parameter 1.
* @param param2 Parameter 2.
* @return A new instance of fragment DiaryFragment.
*/
// TODO: Rename and change types and number of parameters
public static DiaryFragment newInstance(String param1, String param2) {
DiaryFragment fragment = new DiaryFragment();
Bundle args = new Bundle();
args.putString(ARG_DIARY, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
public DiaryFragment() {
// Required empty public constructor
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_DIARY);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_diary, container, false);
// Declare the database to retrieve all the data from the table
DatabaseHelper _dbHelper = DBMgr.openConnection(getContext());
rth = new RecordsTableHelper(_dbHelper.getDatabase());
// Get all the records value and store inside an array list
mRecordsArrayList = new ArrayList<Records>(rth.getAllRecords());
Collections.sort(mRecordsArrayList, new RecordsComparator()); // Sort all the arraylist according to its date time
//mRecordsArrayListSize = mRecordsArrayList.size();
mDiaryListView = (ListView)view.findViewById(R.id.listViewDiary);
mDiaryListView.setOnItemClickListener(new OnPlandetailsitemClickListener());
setHasOptionsMenu(true);
return view;
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_diary, menu);
super.onCreateOptionsMenu(menu,inflater);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_adddiary) {
Intent intent = new Intent(getActivity(), NewDiaryActivity.class);
startActivityForResult(intent, ActivityResults.newdiaryactivityresult);
// Create Animation
getActivity().overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left);
}
return super.onOptionsItemSelected(item);
}
@Override
public void onResume() {
super.onResume();
// Get the total day sum from the database
int totalUniqueDays = getTotalUniqueDays();
/* Declare the database to retrieve all the data from the table
DatabaseHelper _dbHelper = DBMgr.openConnection(getContext());
rth = new RecordsTableHelper(_dbHelper.getDatabase());
*/
// 1) Create a for loop
for (int i = 0; i<mRecordsArrayList.size(); i++) {
Log.d("NON REPEATED DAYS", FormatterMgr.DB_DATE.format(mRecordsArrayList.get(i).getRecordCreatedOn()));
// Set the first column header
if (i==0) {
// Add it into the arraylist
mRecordsArrayList.get(i).setDateHead(true);
}
// 2) Inside the for loop, set the comparison of unique value occurs in the record array list method by checking the getUniqueDaysPos method
// 3) If the unique value occurred, set the date head inside the arraylist
// 4) Store the arraylist into the adapter
/*
// Get the total number of repeated days
int totalRepeatedDays = getTotalRepeatedDays(mRecordsArrayList.get(i).getRecordCreatedOn());
for (int j = 0; j<totalRepeatedDays; j++) {
if (j==0) {
// Add it into the arraylist
mRecordsArrayList.get(j).setDateHead(true);
}
}
*/
}
DiaryListAdapter adapter = new DiaryListAdapter(getActivity(),
R.layout.lv_diarycontent_adapter, mRecordsArrayList);
mDiaryListView.setAdapter(adapter);
}
//response the click on listview
//the click listener for pastplan listview
private class OnPlandetailsitemClickListener implements ListView.OnItemClickListener {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
DiaryListAdapter adapter = (DiaryListAdapter) mDiaryListView.getAdapter();
adapter.setSelectedItem(position);
mDiaryListView.setAdapter(adapter);
// Get the ID
Records _records = (Records)view.getTag(R.id.TAG_DIARY_LIST_ID);
//Direct to the reminder info activity
Intent intent = new Intent(getActivity(), NewDiaryActivity.class);
intent.putExtra(IntentResults.newDiary_id_val, _records.getRecord_id());
startActivityForResult(intent, ActivityResults.inforeminderactivityresult);
// Create Animation
getActivity().overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left);
}
}
// Get the overall number of non repeated days inside record database
public int getTotalUniqueDays() {
// Declare the current date and next date as 0
String currentDate, nextDate = null;
// Declare the result as 0. The result will be produce the outcome of the final result
int result = 0;
ArrayList<String> tempRecordsArrayList = new ArrayList<String>();
// Declare the database to retrieve all the data from the table
for (int i = 0; i<mRecordsArrayList.size(); i++) {
// Convert the date time to date
currentDate = FormatterMgr.DB_DATE.format(mRecordsArrayList.get(i).getRecordCreatedOn());
tempRecordsArrayList.add(currentDate);
}
uniqueSet = new HashSet<String>();
uniqueSet.addAll(tempRecordsArrayList);
return uniqueSet.size();
}
public ArrayList<Integer> getUniqueDaysPos() {
// 1) Get the unique set and store into arraylist
ArrayList<String> tempUniqueSet = new ArrayList<String>(uniqueSet);
// 2) Get the full set of record array list
ArrayList<Records> tempRecordsSet = mRecordsArrayList;
// 3) Create the object of null arraylist integer
ArrayList<Integer> uniqueDaysPos = new ArrayList<Integer>();
// 4) Loop through the fullset arraylist and produce the result of the position of unique dates inside the full set of array list
for (int i = 0; i<tempRecordsSet.size(); i++) {
// 5) Store the unique dates position inside the set of integer arraylist
uniqueDaysPos.add(tempRecordsSet.indexOf(tempUniqueSet));
}
return uniqueDaysPos;
}
public int getTotalRepeatedDays(Date dateValue) {
// Declare the database to retrieve all the data from the table
DatabaseHelper _dbHelper = DBMgr.openConnection(getContext());
rth = new RecordsTableHelper(_dbHelper.getDatabase());
// Get all the records value and store inside an array list
ArrayList<Records> mRecordsDateRepeatedList = rth.getAllRecordsByDate(dateValue);
return mRecordsDateRepeatedList.size();
}
}
下面是列表适配器的 lv_diarycontent_adapter XML 文件。在这种情况下,DiaryListAdapter 背后的代码将根据每条记录的条件切换标题。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- START OF HEAD LAYOUT -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="15dp"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:orientation="horizontal"
android:id="@+id/ll_diaryhead"
android:background="@color/colorPrimary">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.3">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Mon 1, 1976"
android:id="@+id/itemDate"
android:layout_alignParentLeft="true"
android:textAppearance="?android:attr/textAppearanceListItemSmall"
android:textStyle="bold"
android:textColor="@color/font_color_white"
android:layout_marginBottom="5dp" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.7">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
android:id="@+id/itemToday"
android:textAppearance="?android:attr/textAppearanceListItemSmall"
android:textStyle="bold"
android:textColor="@color/font_color_white" />
</LinearLayout>
</LinearLayout>
<!-- END OF HEAD LAYOUT -->
<!-- START OF BODY LAYOUT -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.25"
android:gravity="center_horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="10:30"
android:id="@+id/itemTime"
android:textAppearance="?android:attr/textAppearanceListItemSmall"
android:layout_marginBottom="5dp" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:gravity="center_horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="120/75"
android:id="@+id/itemSysDia"
android:textAppearance="?android:attr/textAppearanceListItemSmall"
></TextView>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.25"
android:gravity="center_horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="80"
android:id="@+id/itemPulse"
android:textAppearance="?android:attr/textAppearanceListItemSmall"
></TextView>
</LinearLayout>
</LinearLayout>
<!-- END OF BODY LAYOUT -->
我现在不得不创建 ListView 并将记录分组到日期中。 到目前为止,我的尝试是按日期按升序对记录进行排序,并用数据填充 ListView 。我尝试使用嵌套的 for 循环和唯一天数,并在其中循环重复的天数。但是,它不起作用。
感谢您花时间阅读本文,如果您有任何疑问,我们很乐意回答您的所有问题!
最佳答案
- 创建一个项目
复制并粘贴到 activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <!-- Content Here --> <LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight=".1" android:background="#f1e7ce" android:orientation="vertical"> <ListView android:id="@+id/listview" android:layout_width="match_parent" android:layout_height="wrap_content"/> </LinearLayout> </LinearLayout>
创建section_header.xml 并粘贴以下代码
<?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/section_header" android:layout_width="match_parent" android:layout_height="30dp" android:background="#ff0092f4" android:textColor="#FFFFFF" android:text="Header" android:textSize="17sp" android:padding="4dp" /> </LinearLayout>
创建row_item.xml 并粘贴以下代码
<?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="horizontal" > <TextView android:id="@+id/time_time" android:layout_width="0dp" android:layout_height="70dp" android:layout_weight="1" android:textSize="20sp" android:text="12.00 PM" android:layout_marginLeft="15dp" android:gravity="center_vertical" android:textColor="#cc222222"/> <TextView android:id="@+id/tv_item_sysdia" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:textSize="15sp" android:text="120/75" android:textColor="#cc222222" android:layout_marginRight="10dp" android:gravity="center_vertical|center"/> <TextView android:id="@+id/tv_item_plus" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:textSize="15sp" android:text="80" android:textColor="#cc222222" android:layout_marginRight="10dp" android:gravity="center_vertical|center"/> </LinearLayout>
创建类 ItemModel 并粘贴以下代码
public class ItemModel implements Comparable<ItemModel>{ private boolean isSectionHeader; private String itemTime; private String itemSysDia; private String itemPulse; private String date; public ItemModel(String itemTime, String itemSysDia, String itemPulse, String date) { this.itemTime = itemTime; this.itemSysDia = itemSysDia; this.itemPulse = itemPulse; this.date =date; isSectionHeader = false; } public String getItemTime() { return itemTime; } public void setItemTime(String itemTime) { this.itemTime = itemTime; } public String getItemSysDia() { return itemSysDia; } public void setItemSysDia(String itemSysDia) { this.itemSysDia = itemSysDia; } public String getItemPulse() { return itemPulse; } public void setItemPulse(String itemPulse) { this.itemPulse = itemPulse; } public String getDate() { return date; } public void setDate(String date) { this.date = date; } public boolean isSectionHeader() { return isSectionHeader; } @Override public int compareTo(ItemModel itemModel) { return this.date.compareTo(itemModel.date); } public void setToSectionHeader() { isSectionHeader = true; } }
在MainActivity中粘贴下面的代码
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ArrayList<ItemModel> itemsList = new ArrayList<>(); ListView list = (ListView) findViewById(R.id.listview); itemsList = sortAndAddSections(getItems()); ListAdapter adapter = new ListAdapter(this, itemsList); list.setAdapter(adapter); } private ArrayList sortAndAddSections(ArrayList<ItemModel> itemList) { ArrayList<ItemModel> tempList = new ArrayList<>(); //First we sort the array Collections.sort(itemList); //Loops thorugh the list and add a section before each sectioncell start String header = ""; for(int i = 0; i < itemList.size(); i++) { //If it is the start of a new section we create a new listcell and add it to our array if(!(header.equals(itemList.get(i).getDate()))) { ItemModel sectionCell = new ItemModel(null, null,null,itemList.get(i).getDate()); sectionCell.setToSectionHeader(); tempList.add(sectionCell); header = itemList.get(i).getDate(); } tempList.add(itemList.get(i)); } return tempList; } public class ListAdapter extends ArrayAdapter { LayoutInflater inflater; public ListAdapter(Context context, ArrayList items) { super(context, 0, items); inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); } @Override public View getView(int position, View convertView, ViewGroup parent) { View v = convertView; ItemModel cell = (ItemModel) getItem(position); //If the cell is a section header we inflate the header layout if(cell.isSectionHeader()) { v = inflater.inflate(R.layout.section_header, null); v.setClickable(false); TextView header = (TextView) v.findViewById(R.id.section_header); header.setText(cell.getDate()); } else { v = inflater.inflate(R.layout.row_item, null); TextView time_time = (TextView) v.findViewById(R.id.time_time); TextView tv_item_sysdia = (TextView) v.findViewById(R.id.tv_item_sysdia); TextView tv_item_plus = (TextView) v.findViewById(R.id.tv_item_plus); time_time.setText(cell.getItemTime()); tv_item_sysdia.setText(cell.getItemSysDia()); tv_item_plus.setText(cell.getItemPulse()); } return v; } } private ArrayList<ItemModel> getItems(){ ArrayList<ItemModel> items = new ArrayList<>(); items.add(new ItemModel("10.30", "120/10","80","Tue,31 Oct 17")); items.add(new ItemModel("10.30", "142/95","95","Tue,31 Oct 17")); items.add(new ItemModel("15.30", "120/95","200","Tue,31 Oct 17")); items.add(new ItemModel("20.30", "120/10","80","Tue,29 Oct 17")); items.add(new ItemModel("10.30", "120/10","50","Tue,29 Oct 17")); items.add(new ItemModel("10.30", "140/10","80","Tue,28 Oct 17")); items.add(new ItemModel("10.30", "30/75","40","Tue,28 Oct 17")); items.add(new ItemModel("10.30", "150/80","70","Tue,28 Oct 17")); return items; } }
您可以从 GitHub 下载该项目:https://github.com/enamul95/CustomHeaderWith
可以看教程链接:http://www.iyildirim.com/tech-blog/creating-listview-with-sections
关于java - 如何创建自定义 Android Listview 标题并将它们分组为几天,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38427007/