Android Studio:将推送通知从EditText迁移至ListView并实现表格展示
解决方案:用双列ListView替代EditText展示通知消息
没问题!要把你的通知消息改成双列ListView(日期时间+消息内容)展示,咱们一步步来实现:
1. 创建数据模型类
首先定义一个Event类,用来封装每条通知的时间和消息内容,方便后续统一处理:
public class Event { private String time; private String message; public Event(String time, String message) { this.time = time; this.message = message; } // Getter方法,用于Adapter获取数据 public String getTime() { return time; } public String getMessage() { return message; } }
2. 设计ListView的列表项布局
创建res/layout/item_event.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="wrap_content" android:orientation="horizontal" android:padding="12dp" android:gravity="center_vertical"> <!-- 左侧:日期时间 --> <TextView android:id="@+id/tv_time" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:textSize="14sp" android:textColor="#333333"/> <!-- 右侧:消息内容 --> <TextView android:id="@+id/tv_message" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:textSize="14sp" android:textColor="#FF5722" android:gravity="end"/> </LinearLayout>
3. 实现自定义ListView适配器
创建EventAdapter,继承BaseAdapter,负责把Event数据绑定到列表项布局:
public class EventAdapter extends BaseAdapter { private Context context; private List<Event> eventList; public EventAdapter(Context context, List<Event> eventList) { this.context = context; this.eventList = eventList; } @Override public int getCount() { return eventList.size(); } @Override public Object getItem(int position) { return eventList.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; if (convertView == null) { convertView = LayoutInflater.from(context).inflate(R.layout.item_event, parent, false); holder = new ViewHolder(); holder.tvTime = convertView.findViewById(R.id.tv_time); holder.tvMessage = convertView.findViewById(R.id.tv_message); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } Event event = eventList.get(position); holder.tvTime.setText(event.getTime()); holder.tvMessage.setText(event.getMessage()); return convertView; } // 优化ListView性能的ViewHolder static class ViewHolder { TextView tvTime; TextView tvMessage; } }
4. 修改主Activity代码,替换EditText为ListView
接下来修改你的主Activity代码,核心是:
- 初始化ListView和事件列表
- 调整文件读写逻辑,适配结构化的Event数据
- 替换Firebase监听中的EditText更新逻辑为ListView更新
步骤4.1:更新Activity布局
把原来布局中的EditText替换为ListView,比如:
<!-- 主布局中的ListView --> <ListView android:id="@+id/list_view_events" android:layout_width="match_parent" android:layout_height="match_parent"/>
步骤4.2:修改Activity逻辑代码
public class MainActivity extends AppCompatActivity { private ListView listViewEvents; private EventAdapter eventAdapter; private List<Event> eventList = new ArrayList<>(); private FirebaseDatabase database; private DatabaseReference myRef, myRef1, myRef2; private Long val = 0L, val1 = 0L, val2 = 0L; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 初始化ListView和Adapter listViewEvents = findViewById(R.id.list_view_events); eventAdapter = new EventAdapter(this, eventList); listViewEvents.setAdapter(eventAdapter); // 从文件加载历史事件 loadEventsFromFile(); // 初始化Firebase引用 database = FirebaseDatabase.getInstance(); myRef = database.getReference("Fall_Detection_Status"); myRef1 = database.getReference("Fall_Detection_Status1"); myRef2 = database.getReference("Seizure"); // Fall检测监听 myRef.addValueEventListener(new ValueEventListener() { @Override public void onDataChange(DataSnapshot dataSnapshot) { val = dataSnapshot.getValue(Long.class); checkAndAddEvent(); } @Override public void onCancelled(DatabaseError databaseError) {} }); myRef1.addValueEventListener(new ValueEventListener() { @Override public void onDataChange(DataSnapshot dataSnapshot) { val1 = dataSnapshot.getValue(Long.class); checkAndAddEvent(); } @Override public void onCancelled(DatabaseError databaseError) {} }); // Seizure检测监听 myRef2.addValueEventListener(new ValueEventListener() { @Override public void onDataChange(DataSnapshot dataSnapshot) { val2 = dataSnapshot.getValue(Long.class); if (val2 != null && val2.longValue() == 1) { String currentTime = Calendar.getInstance().getTime().toString(); String message = "Seizure Detected"; addNewEvent(currentTime, message); // 重置Firebase值 myRef2.setValue(0); } } @Override public void onCancelled(DatabaseError databaseError) {} }); // 初始重置Firebase值 myRef.setValue(0); myRef1.setValue(0); myRef2.setValue(0); } // 统一处理Fall检测的事件添加逻辑 private void checkAndAddEvent() { if (val != null && val1 != null && val.longValue() == 1 && val1.longValue() == 1) { String currentTime = Calendar.getInstance().getTime().toString(); String message = "Fall Detected"; addNewEvent(currentTime, message); // 重置Firebase值 myRef.setValue(0); myRef1.setValue(0); } } // 添加新事件并更新UI和文件 private void addNewEvent(String time, String message) { Event newEvent = new Event(time, message); eventList.add(0, newEvent); // 新事件添加到列表顶部 eventAdapter.notifyDataSetChanged(); // 通知Adapter刷新UI writeEventToFile(newEvent); // 写入文件保存 } // 从文件加载历史事件 private void loadEventsFromFile() { BufferedReader reader = null; try { reader = new BufferedReader(new InputStreamReader(openFileInput("events.txt"))); String line; while ((line = reader.readLine()) != null) { // 按分隔符分割时间和消息(这里用"|"作为分隔符) String[] parts = line.split("\\|", 2); if (parts.length == 2) { eventList.add(new Event(parts[0], parts[1])); } } eventAdapter.notifyDataSetChanged(); } catch (FileNotFoundException e) { // 文件不存在,初始化空列表即可 } catch (IOException e) { e.printStackTrace(); } finally { if (reader != null) { try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } } } // 把单个Event写入文件 private void writeEventToFile(Event event) { try { OutputStreamWriter writer = new OutputStreamWriter(openFileOutput("events.txt", Context.MODE_APPEND)); // 用"|"分隔时间和消息,方便后续读取 writer.write(event.getTime() + "|" + event.getMessage() + "\n"); writer.close(); } catch (IOException e) { Log.e("Exception", "File write failed: " + e.toString()); } } }
关键说明
- 数据结构化:用
Event类统一管理每条通知的时间和消息,比原来的纯文本更易维护; - 文件存储优化:改用
|作为分隔符存储每条事件,读取时可以直接分割成时间和消息,避免原来的换行混乱; - UI更新效率:自定义
EventAdapter结合ViewHolder模式,保证ListView滚动流畅; - 逻辑简化:把重复的事件添加逻辑抽成
addNewEvent方法,代码更简洁; - 新事件置顶:用
eventList.add(0, newEvent)把最新事件放在列表最上方,符合通知类应用的使用习惯。
内容的提问来源于stack exchange,提问作者Moustapha Sabbagh
相关产品推荐
相关产品推荐

