You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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());
        }
    }
}

关键说明

  1. 数据结构化:用Event类统一管理每条通知的时间和消息,比原来的纯文本更易维护;
  2. 文件存储优化:改用|作为分隔符存储每条事件,读取时可以直接分割成时间和消息,避免原来的换行混乱;
  3. UI更新效率:自定义EventAdapter结合ViewHolder模式,保证ListView滚动流畅;
  4. 逻辑简化:把重复的事件添加逻辑抽成addNewEvent方法,代码更简洁;
  5. 新事件置顶:用eventList.add(0, newEvent)把最新事件放在列表最上方,符合通知类应用的使用习惯。

内容的提问来源于stack exchange,提问作者Moustapha Sabbagh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:42:17