我的目标是创建一个应用程序,显示按日期分组的数据列表。请参阅以下实际截图。
为了实现这个设计,我使用了自定义arraylist适配器来实现这种设计。以下是 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 。这是我编写列表视图以在页面内显示的文件后面的UI代码。这是我无法尝试显示列表视图并按日期分组的代码。
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并将记录分组到日期。 到目前为止,我的尝试是按日期按升序对记录进行排序,并使用数据填充列表视图。我尝试使用嵌套的for循环与唯一天数,并循环重复的日期。但是,它不起作用。
感谢您抽出时间阅读本文,如果您有任何疑问,我将很乐意回答您的所有问题!
答案 0 :(得分:2)
copy&amp;粘贴到 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 &amp;粘贴波纹管代码
<?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 &amp;粘贴波纹管代码
<?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 &amp;粘贴波纹管代码
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
答案 1 :(得分:0)
我认为您的问题是在ListView中实现不同的类型项布局。并且使用BaseAdapter而不是ArrayAdapter更容易实现。希望这个{{3}}可以帮助你:)