精华内容
下载资源
问答
  • Materialist, 使用材料设计的Android待办事项列表 MaterialistMaterialist是用于管理任务的最小待办事项列表。 免费,没有广告,使用材料设计。Materialist与其他待办事项列表有什么不同? 许多待办事项列表要么过于...
  • 习惯应用 具有添加,搜索和完整的待办事项功能的待办事项应用程序。 待办事项存储在本地设备上,以便快速访问。 使用的技术 Android Room,用于本地数据库存储待办事项
  • 用户待办事项Android
  • 待办事项清单AndroidAPP 待办事项清单android
  • android-todo ToDo app which showcases Offline-first MVP architecture with Dependency Injection
  • 1:创建待办事项的显示与完成待办事项时的显示 2:搜索已经存在的代办事项 3:日历(阳历阴历转换) 代码如下: MainActivity.java如下: public class MainActivity extends AppCompatActivity { private Button ...

    一:实现功能
    1:创建待办事项的显示与完成待办事项时的显示
    2:搜索已经存在的代办事项
    3:日历(阳历阴历转换)
    代码如下:
    MainActivity.java如下:
    public class MainActivity extends AppCompatActivity {
    private Button EXEInout, EXESearch;
    private Button btn_List,btn_Calendar,btn_Complete;
    private static EditText InputContent, SearchContent,SerialNumber,SearchSerialNumber;
    private static EditText GetContent,GetSerialNumber,GetContent1,GetSerialNumber1,GetContent2,GetSerialNumber2;
    private CheckBox checkBox,checkBox1,checkBox2;
    public static int count = 1;
    public static String ID = null;
    public static String Content = null;
    Dao dao = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        EXEInout = (Button) findViewById(R.id.exeInput);
        EXESearch = (Button) findViewById(R.id.exeSearch);
        btn_Complete = (Button) findViewById(R.id.Complete);
        btn_List = (Button) findViewById(R.id.List);
        btn_Calendar = (Button) findViewById(R.id.Calendar);
        GetContent = (EditText) findViewById(R.id.GetContent);
        GetSerialNumber = (EditText) findViewById(R.id.GetSerialNumber);//序号
        GetContent1 = (EditText) findViewById(R.id.GetContent1);
        GetSerialNumber1 = (EditText) findViewById(R.id.GetSerialNumber1);//序号
        GetContent2 = (EditText) findViewById(R.id.GetContent2);
        GetSerialNumber2 = (EditText) findViewById(R.id.GetSerialNumber2);//序号
        SerialNumber = (EditText) findViewById(R.id.SerialNumber);
        checkBox = (CheckBox) findViewById(R.id.checkbox);
        checkBox1 = (CheckBox) findViewById(R.id.checkbox1);
        checkBox2 = (CheckBox) findViewById(R.id.checkbox2);
        InputContent = (EditText) findViewById(R.id.inputContent);
        SearchContent = (EditText) findViewById(R.id.SearchContent);
        SearchSerialNumber = (EditText) findViewById(R.id.SearchSerialNumber);
        //用于查找待办事项
        EXESearch.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dao = new Dao(MainActivity.this);
                String SearchID = SearchSerialNumber.getText().toString();
                String Content = dao.Query(SearchID);
                SearchContent.setText(Content);
            }
        });
        //用于添加待办事项
        EXEInout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                    dao = new Dao(MainActivity.this);
                    ID = SerialNumber.getText().toString();
                    Content = InputContent.getText().toString();
                    if (ID.equals("") && Content.equals(""))
                    {
                        Toast.makeText(MainActivity.this,"输入的待办事项不能为空",Toast.LENGTH_SHORT).show();
                        return ;
                    }
                    dao.Insert(new DataBase(ID,Content));
                    if (count == 1) {
                        GetSerialNumber.setVisibility(View.VISIBLE);
                        GetContent.setVisibility(View.VISIBLE);
                        checkBox.setVisibility(View.VISIBLE);//可见
                        GetSerialNumber.setText(ID);
                        GetContent.setText(Content);
                    }
                    if (count == 2)
                    {
                        GetSerialNumber1.setVisibility(View.VISIBLE);
                        GetContent1.setVisibility(View.VISIBLE);
                        checkBox1.setVisibility(View.VISIBLE);//可见
                        GetSerialNumber1.setText(ID);
                        GetContent1.setText(Content);
    
                    }
                if (count == 3)
                {
                    GetSerialNumber2.setVisibility(View.VISIBLE);
                    GetContent2.setVisibility(View.VISIBLE);
                    checkBox2.setVisibility(View.VISIBLE);//可见
                    GetSerialNumber2.setText(ID);
                    GetContent2.setText(Content);
    
                }
                count++;
                if (count > 3)
                    Toast.makeText(MainActivity.this,"待办事项存在太多了,请做完一些在添加吧!",Toast.LENGTH_SHORT).show();
                Log.d("Count",count+"");
                Log.d(Dao.TAG,ID);
                Log.d(Dao.TAG,Content);
                //清除数据库专用
                //for (int i = 0; i< 50;i++)
                    //dao.Delete(i+"");
               // setListen();
            }
        });
        //(可见不可见占位置,只是消失,隐藏不会占据屏幕位置)
        //如果被选择就使checkbox,序号,EditText三个为隐藏,并传到另一个一个页面
     //用于提交待办事项(表示已完成)
     btn_Complete.setOnClickListener(new View.OnClickListener() {
         @Override
         public void onClick(View v) {
             Intent intent = null;
             switch (JudgeCheckBoxStatus()) {
                 case 1:
                     GetContent.setVisibility(View.GONE);
                     GetSerialNumber.setVisibility(View.GONE);
                     checkBox.setVisibility(View.GONE);
                     count--;//完成一件待办事项,减少一次计数,方便下一次添加待办事项
                     intent = new Intent(MainActivity.this, Completed.class);
                     break;
                 case 2:
                     GetContent1.setVisibility(View.GONE);
                     GetSerialNumber1.setVisibility(View.GONE);
                     checkBox1.setVisibility(View.GONE);
                     count--;//完成一件待办事项,减少一次计数,方便下一次添加待办事项
                     intent = new Intent(MainActivity.this, Completed.class);
                     break;
                 case 3:
                     GetContent2.setVisibility(View.GONE);
                     GetSerialNumber2.setVisibility(View.GONE);
                     checkBox2.setVisibility(View.GONE);
                     count--;//完成一件待办事项,减少一次计数,方便下一次添加待办事项
                     intent = new Intent(MainActivity.this, Completed.class);
                     break;
             }
             startActivity(intent);
         }
     });
     //跳转到日历视图
     btn_Calendar.setOnClickListener(new View.OnClickListener() {
         @Override
         public void onClick(View v) {
             Intent intent = null;
             intent = new Intent(MainActivity.this, CalendarDemo.class);
                    startActivity(intent);
         }
     });
    
    }
    //用于判断是否已经完成,存在漏洞
    int  JudgeCheckBoxStatus(){
        if (checkBox.isChecked() == true){
            return 1;
        }
        if (checkBox1.isChecked() == true){
            return 2;
        }
        if (checkBox2.isChecked() == true){
            return 3;
        }
        return 0;
    }
    }
    /***************************************************************************分割线*******************************************************************/
    

    在这里插入图片描述
    activity_main.xml代码如下:









        <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="25dp"
                android:textAllCaps="false"
                android:text="----------------全部----------------"
                android:textSize="20sp"
                android:gravity="center"
                android:layout_below="@+id/SearchContent"/>
        <CheckBox
                android:id="@+id/checkbox"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginLeft="0dp"
                android:layout_marginTop="105dp"
                android:visibility="invisible"
                android:layout_below="@id/Search"
    
        />
        <EditText
                android:id="@+id/GetSerialNumber"
                android:layout_height="wrap_content"
                android:layout_width="40dp"
                android:text=""
                android:layout_marginLeft="40dp"
                android:layout_marginTop="85dp"
                android:textSize="25sp"
                android:visibility="invisible"
                android:layout_below="@+id/SearchContent"
    
        />
        <EditText
                android:id="@+id/GetContent"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text=""
                android:textSize="25sp"
                android:layout_marginTop="86dp"
                android:layout_marginLeft="80dp"
                android:visibility="invisible"
                android:layout_below="@+id/exeSearch"
    
    
        />
        <CheckBox
                android:id="@+id/checkbox1"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginLeft="0dp"
                android:layout_marginTop="50dp"
                android:visibility="invisible"
                android:layout_below="@id/checkbox"
    
        />
        <EditText
                android:id="@+id/GetSerialNumber1"
                android:layout_height="wrap_content"
                android:layout_width="40dp"
                android:text=""
                android:layout_marginLeft="40dp"
                android:layout_marginTop="20dp"
                android:textSize="25sp"
                android:visibility="invisible"
                android:layout_below="@+id/GetSerialNumber"
    
        />
        <EditText
                android:id="@+id/GetContent1"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text=""
                android:textSize="25sp"
                android:layout_marginTop="20dp"
                android:layout_marginLeft="80dp"
                android:visibility="invisible"
                android:layout_below="@+id/GetContent"
        />
        <CheckBox
                android:id="@+id/checkbox2"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginLeft="0dp"
                android:layout_marginTop="50dp"
                android:visibility="invisible"
                android:layout_below="@id/checkbox1"
    
        />
        <EditText
                android:id="@+id/GetSerialNumber2"
                android:layout_height="wrap_content"
                android:layout_width="40dp"
                android:text=""
                android:layout_marginLeft="40dp"
                android:layout_marginTop="20dp"
                android:textSize="25sp"
                android:visibility="invisible"
                android:layout_below="@+id/GetSerialNumber1"
    
        />
        <EditText
                android:id="@+id/GetContent2"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text=""
                android:textSize="25sp"
                android:layout_marginTop="22dp"
                android:layout_marginLeft="80dp"
                android:visibility="invisible"
                android:layout_below="@+id/GetContent1"
        />
        <Button
                android:id="@+id/List"
                android:layout_height="50dp"
                android:layout_width="120dp"
                android:text="List"
                android:textAllCaps="false"
                android:layout_marginTop="500dp"
                android:layout_alignParentLeft="true"
            />
        <Button
                android:id="@+id/Complete"
                android:layout_height="50dp"
                android:layout_width="120dp"
                android:layout_marginLeft="150dp"
                android:text="Complete"
                android:textAllCaps="false"
                android:layout_marginTop="90dp"
                android:layout_below="@+id/GetContent2"/>
        <Button
                android:id="@+id/Calendar"
                android:layout_height="50dp"
                android:layout_width="120dp"
                android:text="Calendar"
                android:textAllCaps="false"
                android:layout_marginTop="500dp"
                android:layout_alignParentRight="true"
                />
    
    </RelativeLayout>
    <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
    
    
    </RelativeLayout>
    
    /***************************************************************************分割线*******************************************************************/ Completed.java代码如下 public class Completed extends AppCompatActivity { private Button btn_Receive; private RecyclerView recyclerView; private List dataBaseList = new ArrayList<>(); private MyRecyclerView myRecyclerView; private DataBase dataBase; private TextView Title; private int count = 1; Dao dao = null; private String GetContent = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_completed);
        Title = (TextView) findViewById(R.id.Title);
        recyclerView = (RecyclerView) findViewById(R.id.RecyclerViewItem);
        btn_Receive = (Button) findViewById(R.id.EXE_Receive);
    
        //设置布局管理器
        LinearLayoutManager layoutManager = new LinearLayoutManager(Completed.this);
        recyclerView.setLayoutManager(layoutManager);
        //设置适配器
        myRecyclerView = new MyRecyclerView(dataBaseList);
        recyclerView.setAdapter(myRecyclerView);
    
        btn_Receive.setOnClickListener(new Button.OnClickListener() {
            DataBase dataBase = new DataBase();
            @Override
            public void onClick(View v) {
                String CompletedID = MainActivity.ID;
                String CompletedContent = MainActivity.Content;
                if (! ("".equals(CompletedID)) && ( "".equals(CompletedContent)))
                {
                    Toast.makeText(Completed.this,"内容不能为空",Toast.LENGTH_SHORT).show();
                }
                else {
                    dataBase = new DataBase(CompletedID, CompletedContent);//获取实例
                    dataBaseList.add(dataBase);//添加数据
                    myRecyclerView.notifyItemChanged(dataBaseList.size() - 1);
                    recyclerView.scrollToPosition(dataBaseList.size() - 1);
                }
            }
        });
    }
    

    /********分割线/
    activity_completed.xml界面如图所示:
    在这里插入图片描述

    activity_completed.xm代码如下:

    <TextView
            android:id="@+id/Title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="已完成事项"
            android:textSize="25sp"
            android:gravity="center"
            android:textColor="#090909"
            android:layout_marginBottom="20dp"/>
    <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/RecyclerViewItem"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
    <Button
     android:id="@+id/EXE_Receive"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:text="EXE_Receive"
     android:textAllCaps="false"
     android:layout_marginTop="20dp"/>
    
    /***************************************************************************分割线*******************************************************************/ DataBase.java(实例化数据类) 代码如下: public class DataBase { private String id; private String Content; private static final int Check = 1;//用于判断状态待办事项是否已经完成 private static final int NotCheck = 0; public String getId() { return id; } public String getContent() { return Content; }
    public DataBase() {
        super();
    }
    public DataBase(String id, String Content) {
        super();
        this.id = id;
        this.Content = Content;
    }
    }
    

    /********分割线/
    Sqlite数据库代码如下(实现CRUD)
    public class Dao {
    public static final String TAG = “DataBase”;
    private Helper helper ;
    private SQLiteDatabase DB;
    public Dao(Context context)
    {
    helper = new Helper(context);
    }
    public void Insert(DataBase dataBase){
    DB = helper.getReadableDatabase();
    if (DB.isOpen())
    {
    ContentValues values = new ContentValues();
    values.put(Helper.ID,dataBase.getId());
    values.put(Helper.Content,dataBase.getContent());
    long RowId = DB.insert(Helper.TableName,null,values);
    if(RowId == -1)
    Log.i(TAG, “数据插入失败!”);
    else
    Log.i(TAG, “数据插入成功!”+RowId);
    }
    }
    //根据序号删除数据
    //当前id为暂不为序号
    public void Delete(String id){
    DB = helper.getReadableDatabase();
    if (DB.isOpen()){
    String whereClause = “ID = ?”;
    String[] whereArgs = {id + “”};
    int count = DB.delete(Helper.TableName, whereClause, whereArgs);
    if (count > 0)
    Log.i(TAG, "删除了: " + count + “行”);
    else
    Log.i(“todolist”, “数据未删除!”);
    DB.close(); // 数据库关闭
    }
    }
    public void Update(String id ,String Content){
    DB = helper.getWritableDatabase();
    if(DB.isOpen()) { // 如果数据库打开, 执行添加的操作
    ContentValues values = new ContentValues();
    values.put(“ID”,id);
    values.put(“Content”, Content);
    int count = DB.update(Helper.TableName, values, “_ID = ?”, new String[]{id + “”});
    if (count > 0)
    Log.i(TAG, "修改了: " + count + “行”);
    else
    Log.i(“todolist”, “数据未删除!”);
    DB.close(); // 数据库关闭
    }
    }
    public String Query(String id){
    DB = helper.getReadableDatabase();
    //selection查询子句的条件,可以使用主键查询
    String[] columns = {“ID”, “Content”}; // 需要的列
    String selection = “ID = ?”;
    String[] selectionArgs = {id + “”};
    Cursor cursor = DB.query(Helper.TableName,columns,selection,selectionArgs,null,null,null);
    if (cursor.moveToFirst())
    {
    if(cursor != null && cursor.moveToFirst()) {
    //String _id = cursor.getString(0);
    String Content = cursor.getString(1);
    DB.close();
    return Content;
    }
    cursor.close();
    DB.close();
    }
    return null;
    }
    public List QueryAll() {
    DB = helper.getReadableDatabase(); // 获得一个只读的数据库对象
    if(DB.isOpen()) {
    String[] columns = {“ID”, “Content”}; // 需要的列
    String selection = null; // 选择条件, 给null查询所有
    String[] selectionArgs = null; // 选择条件的参数, 会把选择条件中的? 替换成数据中的值
    String groupBy = null; // 分组语句 group by name
    String having = null; // 过滤语句
    String orderBy = null; // 排序
    Cursor cursor = DB.query(Helper.TableName, columns, selection, selectionArgs, groupBy, having, orderBy);
    String id;
    String Content;
    if(cursor != null && cursor.getCount() > 0) {
    List DataBaseList = new ArrayList();
    while(cursor.moveToNext()) { // 向下移一位, 知道最后一位, 不可以往下移动了, 停止.
    id = cursor.getString(0);
    Content = cursor.getString(1);
    DataBaseList.add(new DataBase(id, Content));
    }
    DB.close();
    return DataBaseList;
    }
    DB.close();
    }
    return null;
    }
    }
    /********分割线/
    Helper类代码如下(数据库创建类继承SQLiteOpenHelper)
    public class Helper extends SQLiteOpenHelper {
    public static final String TableName = “ToDoList”;
    public static final String ID = “ID”;
    public static final String Content = “Content”;
    private static final String DataBase = “todolist.db”;
    private static final SQLiteDatabase.CursorFactory Factory = null;
    public static final int version = 1;

    public Helper(@Nullable Context context) {
        super(context, DataBase, Factory, version);
    }
    @Override
    public void onCreate(SQLiteDatabase db) {
        // 操作数据库
        String sql = "create table " + TableName + "("+ID+" varchar(20) primary key, "+Content+" varchar(20));";
        db.execSQL(sql);
    }
    
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("drop table if exists "+TableName);
        onCreate(db);
    }
    

    }
    /********分割线/
    MyRecyclerView类代码如下(继承RecyclerView.Adapter)
    //使用此类必须先导入闭包implementation ‘com.android.support:recyclerview-v7:27.1.1’(闭包版本很多)
    public class MyRecyclerView extends RecyclerView.Adapter<MyRecyclerView.ViewHolder> {
    private List DataBaseList;
    public MyRecyclerView (List DataBaseList)
    {
    this.DataBaseList = DataBaseList;
    }

    @NonNull
    @Override
    //获取布局
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerview_item,parent,false);
        return new ViewHolder(view);
    }
    //给子控件赋值
    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
          DataBase dataBase = DataBaseList.get(position);
          holder.checkBox.setChecked(true);//设置勾选
          holder.SearchSerialNumber.setText(dataBase.getId());//设置完成待办事项的序号
          holder.Content.setText(dataBase.getContent());//设置完成待办事项的内容
    }
    
    @Override
    public int getItemCount() {
        return DataBaseList.size();
    }
    static class ViewHolder extends RecyclerView.ViewHolder {
        CheckBox checkBox;
        EditText SearchSerialNumber,Content;
        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            checkBox = (CheckBox) itemView.findViewById(R.id.RecyclerViewCheckbox);
            SearchSerialNumber = (EditText) itemView.findViewById(R.id.RecyclerViewSerialNumber);
            Content = (EditText) itemView.findViewById(R.id.RecyclerViewContent);
        }
    }
    

    }
    /********分割线/
    Lunar类(用于日历的阳历和阴历转换)
    package com.example.todolistdemo;

    import android.annotation.SuppressLint;

    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Calendar;
    import java.util.Date;

    public class Lunar {
    private final int year;
    private final int month;
    private final int day;
    private boolean leap;
    //阴历月份表示形式
    final static String[] LunarMonthStyle = {“一”, “二”, “三”, “四”, “五”, “六”, “七”, “八”, “九”, “十”, “十一”, “十二”};
    @SuppressLint(“SimpleDateFormat”)
    static SimpleDateFormat chineseDateFormat = new SimpleDateFormat(“yyyy年MM月dd日”);
    final static long[] lunarInfo = new long[]
    {
    0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2,
    0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977,
    0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970,
    0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950,
    0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557,
    0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5d0, 0x14573, 0x052d0, 0x0a9a8, 0x0e950, 0x06aa0,
    0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0,
    0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b5a0, 0x195a6,
    0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570,
    0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x055c0, 0x0ab60, 0x096d5, 0x092e0,
    0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5,
    0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930,
    0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530,
    0x05aa0, 0x076a3, 0x096d0, 0x04bd7, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45,
    0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0};

    //====== 传回农历 y年的总天数
    final private static int yearDays(int y) {
        int i, sum = 348;
        for (i = 0x8000; i > 0x8; i >>= 1) {
            if ((lunarInfo[y - 1900] & i) != 0)
                sum += 1;
        }
        return (sum + leapDays(y));
    }
    
    
    //====== 传回农历 y年闰月的天数
    final private static int leapDays(int y) {
        if (leapMonth(y) != 0) {
            if ((lunarInfo[y - 1900] & 0x10000) != 0)
                return 30;
            else
                return 29;
        } else
            return 0;
    }
    
    
    //====== 传回农历 y年闰哪个月 1-12 , 没闰传回 0
    final private static int leapMonth(int y) {
        return (int) (lunarInfo[y - 1900] & 0xf);
    }
    
    
    //====== 传回农历 y年m月的总天数
    final private static int monthDays(int y, int m) {
        if ((lunarInfo[y - 1900] & (0x10000 >> m)) == 0)
            return 29;
        else
            return 30;
    }
    
    
    //====== 传回农历 y年的生肖
    final public String animalsYear() {
        final String[] Animals = new String[]{"鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊", "猴", "鸡", "狗", "猪"};
        return Animals[(year - 4) % 12];
    }
    
    
    //====== 传入 月日的offset 传回干支, 0=甲子
    final private static String cyclicalm(int num) {
        final String[] TianGan = new String[]{"甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸"};
        final String[] JiaZi = new String[]{"子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥"};
        return (TianGan[num % 10] + JiaZi[num % 12]);
    }
    
    
    //====== 传入 offset 传回干支, 0=甲子
    final public String cyclical() {
        int num = year - 1900 + 36;
        return (cyclicalm(num));
    }
    public String getLunarMonthString() {
        // TODO Auto-generated method stub
        return null;
    }
    
    
    public Lunar(Calendar cal) {
        @SuppressWarnings("unused") int yearCyl, monCyl, dayCyl;
        int leapMonth = 0;
        Date baseDate = null;
        try {
            baseDate = chineseDateFormat.parse("1900年1月31日");
        } catch (ParseException e) {
            e.printStackTrace(); //To change body of catch statement use Options | File Templates.
        }
    
    
        //求出和1900年1月31日相差的天数
        assert baseDate != null;
        int offset = (int) ((cal.getTime().getTime() - baseDate.getTime()) / 86400000L);
        dayCyl = offset + 40;
        monCyl = 14;
    
    
        //用offset减去每农历年的天数
        // 计算当天是农历第几天
        //i最终结果是农历的年份
        //offset是当年的第几天
        int iYear, daysOfYear = 0;
        for (iYear = 1900; iYear < 2050 && offset > 0; iYear++) {
            daysOfYear = yearDays(iYear);
            offset -= daysOfYear;
            monCyl += 12;
        }
        if (offset < 0) {
            offset += daysOfYear;
            iYear--;
            monCyl -= 12;
        }
        //农历年份
        year = iYear;
    
        yearCyl = iYear - 1864;
        leapMonth = leapMonth(iYear); //闰哪个月,1-12
        leap = false;
    
    
        //用当年的天数offset,逐个减去每月(农历)的天数,求出当天是本月的第几天
        int iMonth, daysOfMonth = 0;
        for (iMonth = 1; iMonth < 13 && offset > 0; iMonth++) {
            //闰月
            if (leapMonth > 0 && iMonth == (leapMonth + 1) && !leap) {
                --iMonth;
                leap = true;
                daysOfMonth = leapDays(year);
            } else
                daysOfMonth = monthDays(year, iMonth);
    
    
            offset -= daysOfMonth;
            //解除闰月
            if (leap && iMonth == (leapMonth + 1)) leap = false;
            if (!leap) monCyl++;
        }
        //offset为0时,并且刚才计算的月份是闰月,要校正
        if (offset == 0 && leapMonth > 0 && iMonth == leapMonth + 1) {
            if (leap) {
                leap = false;
            } else {
                leap = true;
                --iMonth;
                --monCyl;
            }
        }
        //offset小于0时,也要校正
        if (offset < 0) {
            offset += daysOfMonth;
            --iMonth;
            --monCyl;
        }
        month = iMonth;
        day = offset + 1;
    }
    
    
    public static String getChinaDayString(int day) {
        String[] chineseTen = {"初", "十", "廿", "三"};
        int n = day % 10 == 0 ? 9 : day % 10 - 1;
        if (day > 30)
            return "";
        if (day == 10)
            return "初十";
        else
            return chineseTen[day / 10] + LunarMonthStyle[n];
    }
    
    
    public String toString() {
        return (leap ? "闰" : "") + LunarMonthStyle[month - 1] + "月" + getChinaDayString(day);
    }
    

    }
    /********分割线/
    日历类主要关于CalendarView再次不多介绍
    图所示:![在这里插入图片描述](https://img-blog.csdnimg.cn/2021013116150059.png
    在这里插入图片描述
    //麻烦大家多给一点建议

    展开全文
  • Android应用源码待办事项提醒项目 无法运行
  • ToDoList:一个简单的待办事项清单Android应用
  • ToDoApp客户端 一个简单的待办事项Android应用程序。
  • PerDiem 在Java / Android Studio中编程的“待办事项”列表Android应用程序。
  • 待办事项 示例Android项目,在待办事项列表模型中显示任务控件
  • 文件夹 PATH 列表 卷序列号为 00000200 3CD2:D088
  • orgzly-android:用于记笔记和管理待办事项列表的Outliner
  • android roomIn this tutorial, we’ll be discussing and implementing the Room library introduced by Google. We’ll be using it to develop a Todo List Android Application. 在本教程中,我们将讨论和实现...

    android room

    In this tutorial, we’ll be discussing and implementing the Room library introduced by Google. We’ll be using it to develop a Todo List Android Application.

    在本教程中,我们将讨论和实现Google引入的Room库。 我们将使用它来开发Todo List Android应用程序。

    安卓室 (Android Room)

    Room is a library introduced by Google that acts as an Abstraction layer over SQLite and makes the database querying easier.

    Room是Google引入的库,可作为SQLite上的抽象层,使数据库查询更加容易。

    It does compile-time verification of SQL queries. Thus preventing runtime crashes.

    它确实对SQL查询进行编译时验证。 从而防止运行时崩溃。

    It reduces the boilerplate code. Instead of using SQLiteHelper and writing lengthy queries, we can use annotations to do the work for us.

    它减少了样板代码。 代替使用SQLiteHelper和编写冗长的查询,我们可以使用注释为我们完成工作。

    Following is the structure of Room library:

    以下是Room库的结构:

    android room architecture

    Google Docs

    谷歌文档

    Typically, Room consists of the following three main components:

    通常,Room由以下三个主要部分组成:

    • Entity: This is a model class in which we define the properties which act as column fields. We can alternatively set column names using the annotation @ColumnInfo We need to set the table name too. To ignore a property from the table, use the annotation @Ignore over it. At least one property must have @PrimaryKey. To set a column name that’s different from the field name, use @Embedded

      Entity :这是一个模型类,我们在其中定义充当列字段的属性。 我们也可以使用注释@ColumnInfo设置列名。我们也需要设置表名。 要忽略表中的属性,请@Ignore使用批注@Ignore 。 至少一个属性必须具有@PrimaryKey 。 若要设置与字段名称不同的列名称,请使用@Embedded
    • Database : This is an abstract class which must extend the RoomDatabase. We must set the Entity here. Also, we need to update the version number everytime we change the schema. Set exportSchema to true/false

      Database :这是一个抽象类,必须扩展RoomDatabase 。 我们必须在这里设置实体。 另外,每次更改架构时,我们都需要更新版本号。 将exportSchema设置为true / false
    • Dao: Data Access Object. This is the interface where we set our SQL queries. @Insert, @Query, @Update @Delete.
      @Insert cannot return an int.
      @Update and @Delete can return an int which represents the number of rows changed/deleted.

      Dao :数据访问对象。 这是我们设置SQL查询的接口。 @Insert@Query@Update @Delete
      @Insert无法返回int。
      @Update和@Delete可以返回一个整数,该整数表示已更改/删除的行数。
    Room queries can’t be and should not be executed on the main thread. It’ll lead to a crash.
    房间查询不能也不应在主线程上执行。 它将导致崩溃。

    Let’s use Room library in our Todo List Android Application.

    让我们在Todo List Android应用程序中使用Room库。

    Android TODO App项目结构 (Android TODO App Project Structure)

    Our application consists of inserting, updating, deleting todos.
    We first need to import the following Room dependency in our build.gradle:

    我们的应用程序包括插入,更新,删除待办事项。
    我们首先需要在build.gradle中导入以下Room依赖项:

    implementation 'android.arch.persistence.room:runtime:1.0.0'
    annotationProcessor 'android.arch.persistence.room:compiler:1.0.0'

    Let’s create the Table for our Database using the Todo.java class as shown below:

    让我们使用Todo.java类为数据库创建表,如下所示:

    package com.journaldev.androidroomtodolist;
    import android.arch.persistence.room.Entity;
    import android.arch.persistence.room.Ignore;
    import android.arch.persistence.room.PrimaryKey;
    
    import java.io.Serializable;
    
    @Entity(tableName = MyDatabase.TABLE_NAME_TODO)
    public class Todo implements Serializable {
    
        @PrimaryKey(autoGenerate = true)
        public int todo_id;
    
        public String name;
    
        public String description;
    
        public String category;
    
        @Ignore
        public String priority;
    
    }

    MyDatabase.java

    MyDatabase.java

    package com.journaldev.androidroomtodolist;
    
    import android.arch.persistence.room.Database;
    import android.arch.persistence.room.RoomDatabase;
    
    @Database(entities = {Todo.class}, version = 1, exportSchema = false)
    public abstract class MyDatabase extends RoomDatabase {
    
        public static final String DB_NAME = "app_db";
        public static final String TABLE_NAME_TODO = "todo";
    
        public abstract DaoAccess daoAccess();
    
    }

    This is an abstract class which contains the definition of the DaoAccess() interface.

    这是一个抽象类,其中包含DaoAccess()接口的定义。

    DaoAccess.java

    DaoAccess.java

    package com.journaldev.androidroomtodolist;
    
    import android.arch.persistence.room.Dao;
    import android.arch.persistence.room.Delete;
    import android.arch.persistence.room.Insert;
    import android.arch.persistence.room.Query;
    import android.arch.persistence.room.Update;
    
    import java.util.List;
    
    @Dao
    public interface DaoAccess {
    
        @Insert
        long insertTodo(Todo todo);
    
        @Insert
        void insertTodoList(List<Todo> todoList);
    
        @Query("SELECT * FROM " + MyDatabase.TABLE_NAME_TODO)
        List<Todo> fetchAllTodos();
    
        @Query("SELECT * FROM " + MyDatabase.TABLE_NAME_TODO + " WHERE category = :category")
        List<Todo> fetchTodoListByCategory(String category);
    
        @Query("SELECT * FROM " + MyDatabase.TABLE_NAME_TODO + " WHERE todo_id = :todoId")
        Todo fetchTodoListById(int todoId);
    
        @Update
        int updateTodo(Todo todo);
    
        @Delete
        int deleteTodo(Todo todo);
    }

    Add the annotations and a few sql queries. And all the SQLite features are ready to be implemented in our Activity.

    添加注释和一些sql查询。 并且所有SQLite功能都可以在我们的Activity中实现。

    The code for the activity_main.xml layout is given below:

    下面给出了activity_main.xml布局的代码:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
        xmlns:tools="https://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">
        
        <Spinner
            android:id="@+id/spinner"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true" />
    
        <android.support.v7.widget.RecyclerView
            android:id="@+id/recyclerView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_below="@+id/spinner"
            android:layout_marginTop="16dp" />
    
    
        <android.support.design.widget.FloatingActionButton
            android:id="@+id/fab"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_alignParentRight="true"
            android:layout_marginBottom="16dp"
            android:src="@android:drawable/ic_input_add"
            android:layout_marginEnd="16dp"
            android:layout_marginRight="16dp" />
    
    </RelativeLayout>

    The code for the recyclerview_item_layout.xml is given below:

    下面给出了recyclerview_item_layout.xml的代码:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
        xmlns:app="https://schemas.android.com/apk/res-auto"
        xmlns:tools="https://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    
        <android.support.v7.widget.CardView
            android:id="@+id/cardView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_margin="16dp">
    
            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="8dp">
    
                <TextView
                    android:id="@+id/txtNo"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_alignParentLeft="true"
                    android:layout_centerVertical="true" />
    
                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_toRightOf="@+id/txtNo"
                    android:orientation="vertical">
    
                    <TextView
                        android:id="@+id/txtName"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginLeft="8dp"
                        android:layout_marginRight="8dp"
                        android:layout_marginTop="8dp"
                        android:textAllCaps="true"
                        android:textColor="@android:color/black" />
    
                    <TextView
                        android:id="@+id/txtDesc"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:layout_marginLeft="8dp"
                        android:layout_marginRight="8dp"
                        android:layout_marginStart="8dp"
                        android:layout_marginTop="8dp"
                        android:ellipsize="end"
                        android:maxLines="1" />
    
                    <TextView
                        android:id="@+id/txtCategory"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginLeft="8dp"
                        android:layout_marginStart="8dp"
                        android:layout_marginTop="8dp"
                        android:textColor="@android:color/holo_red_dark" />
    
                </LinearLayout>
    
    
            </RelativeLayout>
        </android.support.v7.widget.CardView>
    </LinearLayout>

    The code for the MainActivity.java class is given below:

    MainActivity.java类的代码如下:

    package com.journaldev.androidroomtodolist;
    
    import android.annotation.SuppressLint;
    import android.arch.persistence.room.Room;
    import android.content.Intent;
    import android.content.SharedPreferences;
    import android.os.AsyncTask;
    import android.support.design.widget.FloatingActionButton;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.support.v7.widget.LinearLayoutManager;
    import android.support.v7.widget.RecyclerView;
    import android.view.View;
    import android.widget.AdapterView;
    import android.widget.ArrayAdapter;
    import android.widget.Spinner;
    import android.widget.Toast;
    
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    
    public class MainActivity extends AppCompatActivity implements RecyclerViewAdapter.ClickListener, AdapterView.OnItemSelectedListener {
    
        MyDatabase myDatabase;
        RecyclerView recyclerView;
        Spinner spinner;
        RecyclerViewAdapter recyclerViewAdapter;
        FloatingActionButton floatingActionButton;
        private String[] categories = {
                "All",
                "Android",
                "iOS",
                "Kotlin",
                "Swift"
        };
    
        ArrayList<Todo> todoArrayList = new ArrayList<>();
        ArrayList<String> spinnerList = new ArrayList<>(Arrays.asList(categories));
    
        public static final int NEW_TODO_REQUEST_CODE = 200;
        public static final int UPDATE_TODO_REQUEST_CODE = 300;
    
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            initViews();
            myDatabase = Room.databaseBuilder(getApplicationContext(), MyDatabase.class, MyDatabase.DB_NAME).fallbackToDestructiveMigration().build();
            checkIfAppLaunchedFirstTime();
    
            spinner.setOnItemSelectedListener(this);
            spinner.setSelection(0);
    
            floatingActionButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    startActivityForResult(new Intent(MainActivity.this, TodoNoteActivity.class), NEW_TODO_REQUEST_CODE);
                }
            });
    
        }
    
        private void initViews() {
            floatingActionButton = findViewById(R.id.fab);
            spinner = findViewById(R.id.spinner);
            ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, spinnerList);
            adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
            spinner.setAdapter(adapter);
    
    
            recyclerView = findViewById(R.id.recyclerView);
            recyclerView.setLayoutManager(new LinearLayoutManager(this));
            recyclerViewAdapter = new RecyclerViewAdapter(this);
            recyclerView.setAdapter(recyclerViewAdapter);
        }
    
        @Override
        public void launchIntent(int id) {
            startActivityForResult(new Intent(MainActivity.this, TodoNoteActivity.class).putExtra("id", id), UPDATE_TODO_REQUEST_CODE);
        }
    
        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
    
    
            if (position == 0) {
                loadAllTodos();
            } else {
                String string = parent.getItemAtPosition(position).toString();
                loadFilteredTodos(string);
            }
        }
    
        @Override
        public void onNothingSelected(AdapterView<?> parent) {
    
        }
    
    
        @SuppressLint("StaticFieldLeak")
        private void loadFilteredTodos(String category) {
            new AsyncTask<String, Void, List<Todo>>() {
                @Override
                protected List<Todo> doInBackground(String... params) {
                    return myDatabase.daoAccess().fetchTodoListByCategory(params[0]);
    
                }
    
                @Override
                protected void onPostExecute(List<Todo> todoList) {
                    recyclerViewAdapter.updateTodoList(todoList);
                }
            }.execute(category);
    
        }
    
    
        @SuppressLint("StaticFieldLeak")
        private void fetchTodoByIdAndInsert(int id) {
            new AsyncTask<Integer, Void, Todo>() {
                @Override
                protected Todo doInBackground(Integer... params) {
                    return myDatabase.daoAccess().fetchTodoListById(params[0]);
    
                }
    
                @Override
                protected void onPostExecute(Todo todoList) {
                    recyclerViewAdapter.addRow(todoList);
                }
            }.execute(id);
    
        }
    
        @SuppressLint("StaticFieldLeak")
        private void loadAllTodos() {
            new AsyncTask<String, Void, List<Todo>>() {
                @Override
                protected List<Todo> doInBackground(String... params) {
                    return myDatabase.daoAccess().fetchAllTodos();
                }
    
                @Override
                protected void onPostExecute(List<Todo> todoList) {
                    recyclerViewAdapter.updateTodoList(todoList);
                }
            }.execute();
        }
    
        private void buildDummyTodos() {
            Todo todo = new Todo();
            todo.name = "Android Retrofit Tutorial";
            todo.description = "Cover a tutorial on the Retrofit networking library using a RecyclerView to show the data.";
            todo.category = "Android";
    
            todoArrayList.add(todo);
    
            todo = new Todo();
            todo.name = "iOS TableView Tutorial";
            todo.description = "Covers the basics of TableViews in iOS using delegates.";
            todo.category = "iOS";
    
            todoArrayList.add(todo);
    
            todo = new Todo();
            todo.name = "Kotlin Arrays";
            todo.description = "Cover the concepts of Arrays in Kotlin and how they differ from the Java ones.";
            todo.category = "Kotlin";
    
            todoArrayList.add(todo);
    
            todo = new Todo();
            todo.name = "Swift Arrays";
            todo.description = "Cover the concepts of Arrays in Swift and how they differ from the Java and Kotlin ones.";
            todo.category = "Swift";
    
            todoArrayList.add(todo);
            insertList(todoArrayList);
        }
    
        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
    
            if (resultCode == RESULT_OK) {
    
                //reset spinners
                spinner.setSelection(0);
    
                if (requestCode == NEW_TODO_REQUEST_CODE) {
                    long id = data.getLongExtra("id", -1);
                    Toast.makeText(getApplicationContext(), "Row inserted", Toast.LENGTH_SHORT).show();
                    fetchTodoByIdAndInsert((int) id);
    
                } else if (requestCode == UPDATE_TODO_REQUEST_CODE) {
    
                    boolean isDeleted = data.getBooleanExtra("isDeleted", false);
                    int number = data.getIntExtra("number", -1);
                    if (isDeleted) {
                        Toast.makeText(getApplicationContext(), number + " rows deleted", Toast.LENGTH_SHORT).show();
                    } else {
                        Toast.makeText(getApplicationContext(), number + " rows updated", Toast.LENGTH_SHORT).show();
                    }
    
                    loadAllTodos();
    
                }
    
    
            } else {
                Toast.makeText(getApplicationContext(), "No action done by user", Toast.LENGTH_SHORT).show();
            }
        }
    
        @SuppressLint("StaticFieldLeak")
        private void insertList(List<Todo> todoList) {
            new AsyncTask<List<Todo>, Void, Void>() {
                @Override
                protected Void doInBackground(List<Todo>... params) {
                    myDatabase.daoAccess().insertTodoList(params[0]);
    
                    return null;
    
                }
    
                @Override
                protected void onPostExecute(Void voids) {
                    super.onPostExecute(voids);
                }
            }.execute(todoList);
    
        }
    
        private void checkIfAppLaunchedFirstTime() {
            final String PREFS_NAME = "SharedPrefs";
    
            SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
    
            if (settings.getBoolean("firstTime", true)) {
                settings.edit().putBoolean("firstTime", false).apply();
                buildDummyTodos();
            }
        }
    }
    • myDatabase = Room.databaseBuilder(getApplicationContext(), MyDatabase.class, MyDatabase.DB_NAME).fallbackToDestructiveMigration().build(); is used to initialise the database.

      myDatabase = Room.databaseBuilder(getApplicationContext(), MyDatabase.class, MyDatabase.DB_NAME).fallbackToDestructiveMigration().build(); 用于初始化数据库。
    • fallbackToDestructiveMigration() provides seamless migration across database version without crashing.

      fallbackToDestructiveMigration()提供跨数据库版本的无缝迁移而不会崩溃。
    • We check if the app is launched for the first time or not using shared preferences.

      我们会检查应用程序是首次启动还是不使用共享首选项
    • Then we create a dummy ArrayList to populate our RecyclerView.

      然后,我们创建一个虚拟ArrayList来填充RecyclerView
    • We need to use asynchronous tasks to run queries. So either use AsyncTask or go for RxJava. In this tutorial, we’ve used AsyncTasks.

      我们需要使用异步任务来运行查询。 因此,可以使用AsyncTask或使用RxJava 。 在本教程中,我们使用了AsyncTasks。
    • We will have following operations in our app:
      • Updating a Todo Item from the list
      • Adding a new Todo Item to the list.

      我们的应用程序中将执行以下操作:
      • 从列表更新待办事项
      • 将新的待办事项添加到列表中。
    • For either of the cases, we use startActivityForResult to get back the data from the next activity and update the RecyclerView accordingly.

      对于这两种情况,我们都使用startActivityForResult从下一个活动中获取数据并相应地更新RecyclerView。
    • Our spinner is used to filter the RecyclerView based on category for which we Query the database.

      我们的微调器用于根据查询数据库的类别过滤RecyclerView。

    RecyclerViewAdapter.java

    RecyclerViewAdapter.java

    package com.journaldev.androidroomtodolist;
    
    import android.support.v7.widget.CardView;
    import android.support.v7.widget.RecyclerView;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.TextView;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {
    
        private List<Todo> todoList;
        private RecyclerViewAdapter.ClickListener clickListener;
    
        public RecyclerViewAdapter(ClickListener clickListener) {
            this.clickListener = clickListener;
            todoList = new ArrayList<>();
        }
    
        @Override
        public RecyclerViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
                                                                 int viewType) {
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerview_item_layout, parent, false);
            RecyclerViewAdapter.ViewHolder viewHolder = new RecyclerViewAdapter.ViewHolder(view);
            return viewHolder;
        }
    
        @Override
        public void onBindViewHolder(RecyclerViewAdapter.ViewHolder holder, int position) {
            Todo todo = todoList.get(position);
            holder.txtName.setText(todo.name);
            holder.txtNo.setText("#" + String.valueOf(todo.todo_id));
            holder.txtDesc.setText(todo.description);
            holder.txtCategory.setText(todo.category);
    
        }
    
        @Override
        public int getItemCount() {
            return todoList.size();
        }
    
    
        public void updateTodoList(List<Todo> data) {
            todoList.clear();
            todoList.addAll(data);
            notifyDataSetChanged();
        }
    
        public void addRow(Todo data) {
            todoList.add(data);
            notifyDataSetChanged();
        }
    
        public class ViewHolder extends RecyclerView.ViewHolder {
    
            public TextView txtName;
            public TextView txtNo;
            public TextView txtDesc;
            public TextView txtCategory;
            public CardView cardView;
    
            public ViewHolder(View view) {
                super(view);
    
                txtNo = view.findViewById(R.id.txtNo);
                txtName = view.findViewById(R.id.txtName);
                txtDesc = view.findViewById(R.id.txtDesc);
                txtCategory = view.findViewById(R.id.txtCategory);
                cardView = view.findViewById(R.id.cardView);
                cardView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        clickListener.launchIntent(todoList.get(getAdapterPosition()).todo_id);
                    }
                });
            }
        }
    
        public interface ClickListener {
            void launchIntent(int id);
        }
    }

    The code for the activity_todo_note.xml layout is given below:

    下面给出了activity_todo_note.xml布局的代码:

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.design.widget.CoordinatorLayout xmlns:android="https://schemas.android.com/apk/res/android"
        xmlns:app="https://schemas.android.com/apk/res-auto"
        xmlns:tools="https://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".TodoNoteActivity">
    
        <android.support.design.widget.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:theme="@style/AppTheme.AppBarOverlay">
    
            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="?attr/colorPrimary"
                app:popupTheme="@style/AppTheme.PopupOverlay" />
    
        </android.support.design.widget.AppBarLayout>
    
        <include layout="@layout/content_todo_note" />
    
    
    
    </android.support.design.widget.CoordinatorLayout>

    content_todo_note.xml

    content_todo_note.xml

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.constraint.ConstraintLayout xmlns:android="https://schemas.android.com/apk/res/android"
        xmlns:app="https://schemas.android.com/apk/res-auto"
        xmlns:tools="https://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        tools:context=".TodoNoteActivity"
        tools:showIn="@layout/activity_todo_note">
    
    
        <EditText
            android:id="@+id/inTitle"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginEnd="8dp"
            android:layout_marginLeft="8dp"
            android:layout_marginRight="8dp"
            android:layout_marginStart="8dp"
            android:layout_marginTop="16dp"
            android:ems="10"
            android:hint="Title"
            android:text="Sample Title"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    
    
        <EditText
            android:id="@+id/inDescription"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginEnd="8dp"
            android:layout_marginLeft="8dp"
            android:layout_marginRight="8dp"
            android:layout_marginStart="8dp"
            android:layout_marginTop="8dp"
            android:ems="10"
            android:hint="Description"
            android:minLines="3"
            android:text="Sample Description"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.0"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/inTitle" />
    
    
        <Spinner
            android:id="@+id/spinner"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginEnd="8dp"
            android:layout_marginLeft="8dp"
            android:layout_marginRight="8dp"
            android:layout_marginStart="8dp"
            android:layout_marginTop="8dp"
            android:padding="16dp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/inDescription" />
    
        <Button
            android:id="@+id/btnDone"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginEnd="8dp"
            android:layout_marginLeft="8dp"
            android:layout_marginRight="8dp"
            android:layout_marginStart="8dp"
            android:layout_marginTop="16dp"
            android:text="DONE"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/spinner" />
    
        <Button
            android:id="@+id/btnDelete"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:text="DELETE"
            android:visibility="gone"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/btnDone" />
    
    
    </android.support.constraint.ConstraintLayout>

    The code for the TodoNoteActivity.java class is given below

    下面给出了TodoNoteActivity.java类的代码

    package com.journaldev.androidroomtodolist;
    
    import android.annotation.SuppressLint;
    import android.arch.persistence.room.Room;
    import android.content.Intent;
    import android.os.AsyncTask;
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.support.v7.widget.Toolbar;
    import android.view.View;
    import android.widget.ArrayAdapter;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.Spinner;
    
    import java.util.ArrayList;
    import java.util.Arrays;
    
    public class TodoNoteActivity extends AppCompatActivity {
    
        Spinner spinner;
        EditText inTitle, inDesc;
        Button btnDone, btnDelete;
        boolean isNewTodo = false;
    
        private String[] categories = {
                "Android",
                "iOS",
                "Kotlin",
                "Swift"
        };
    
        public ArrayList<String> spinnerList = new ArrayList<>(Arrays.asList(categories));
        MyDatabase myDatabase;
    
        Todo updateTodo;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_todo_note);
            Toolbar toolbar = findViewById(R.id.toolbar);
            setSupportActionBar(toolbar);
    
            spinner = findViewById(R.id.spinner);
            inTitle = findViewById(R.id.inTitle);
            inDesc = findViewById(R.id.inDescription);
            btnDone = findViewById(R.id.btnDone);
            btnDelete = findViewById(R.id.btnDelete);
            ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, spinnerList);
            adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
            spinner.setAdapter(adapter);
    
            myDatabase = Room.databaseBuilder(getApplicationContext(), MyDatabase.class, MyDatabase.DB_NAME).build();
    
            int todo_id = getIntent().getIntExtra("id", -100);
    
            if (todo_id == -100)
                isNewTodo = true;
    
            if (!isNewTodo) {
                fetchTodoById(todo_id);
                btnDelete.setVisibility(View.VISIBLE);
            }
    
            btnDone.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (isNewTodo) {
                        Todo todo = new Todo();
                        todo.name = inTitle.getText().toString();
                        todo.description = inDesc.getText().toString();
                        todo.category = spinner.getSelectedItem().toString();
    
                        insertRow(todo);
                    } else {
    
                        updateTodo.name = inTitle.getText().toString();
                        updateTodo.description = inDesc.getText().toString();
                        updateTodo.category = spinner.getSelectedItem().toString();
    
                        updateRow(updateTodo);
                    }
                }
            });
    
            btnDelete.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    deleteRow(updateTodo);
                }
            });
        }
    
        @SuppressLint("StaticFieldLeak")
        private void fetchTodoById(final int todo_id) {
            new AsyncTask<Integer, Void, Todo>() {
                @Override
                protected Todo doInBackground(Integer... params) {
    
                    return myDatabase.daoAccess().fetchTodoListById(params[0]);
    
                }
    
                @Override
                protected void onPostExecute(Todo todo) {
                    super.onPostExecute(todo);
                    inTitle.setText(todo.name);
                    inDesc.setText(todo.description);
                    spinner.setSelection(spinnerList.indexOf(todo.category));
    
                    updateTodo = todo;
                }
            }.execute(todo_id);
    
        }
    
        @SuppressLint("StaticFieldLeak")
        private void insertRow(Todo todo) {
            new AsyncTask<Todo, Void, Long>() {
                @Override
                protected Long doInBackground(Todo... params) {
                    return myDatabase.daoAccess().insertTodo(params[0]);
                }
    
                @Override
                protected void onPostExecute(Long id) {
                    super.onPostExecute(id);
    
                    Intent intent = getIntent();
                    intent.putExtra("isNew", true).putExtra("id", id);
                    setResult(RESULT_OK, intent);
                    finish();
                }
            }.execute(todo);
    
        }
    
        @SuppressLint("StaticFieldLeak")
        private void deleteRow(Todo todo) {
            new AsyncTask<Todo, Void, Integer>() {
                @Override
                protected Integer doInBackground(Todo... params) {
                    return myDatabase.daoAccess().deleteTodo(params[0]);
                }
    
                @Override
                protected void onPostExecute(Integer number) {
                    super.onPostExecute(number);
    
                    Intent intent = getIntent();
                    intent.putExtra("isDeleted", true).putExtra("number", number);
                    setResult(RESULT_OK, intent);
                    finish();
                }
            }.execute(todo);
    
        }
    
    
        @SuppressLint("StaticFieldLeak")
        private void updateRow(Todo todo) {
            new AsyncTask<Todo, Void, Integer>() {
                @Override
                protected Integer doInBackground(Todo... params) {
                    return myDatabase.daoAccess().updateTodo(params[0]);
                }
    
                @Override
                protected void onPostExecute(Integer number) {
                    super.onPostExecute(number);
    
                    Intent intent = getIntent();
                    intent.putExtra("isNew", false).putExtra("number", number);
                    setResult(RESULT_OK, intent);
                    finish();
                }
            }.execute(todo);
    
        }
    
    }

    setResult(RESULT_OK, intent); is used to pass back the result to the MainActivity.
    We either pass the new todo task’s id or the number of rows deleted/updated and the RecyclerView is updated accordingly.

    setResult(RESULT_OK, intent); 用于将结果传递回MainActivity。
    我们要么传递新的待办任务的ID,要么传递删除/更新的行数,并相应地更新RecyclerView。

    The output of the above application in action is given below.

    android-room-todolist-output

    下面给出了上面应用程序的输出。

    This brings an end to this tutorial on Android Room. Using it we were able to create our first TodoList Application easily and quickly while reducing the boilerplate code of SQLite. You can download the final project from the link given below.

    这样就结束了有关Android Room的本教程。 使用它,我们能够轻松快速地创建我们的第一个TodoList应用程序,同时减少了SQLite的样板代码。 您可以从下面给出的链接下载最终项目。

    翻译自: https://www.journaldev.com/20688/android-room-todo-list-application

    android room

    展开全文
  • Orgzly 用于记笔记和管理待办事项列表的大纲
  • 在这篇文章中,我将向您展示一些适用于Android的最佳免费待办事项列表应用程序。 然后,我将为您提供一些有关如何创建自己的待办事项列表应用程序的指导。 待办事项列表应用程序可让您保持任务井井有条,并确保...

    如果您没有组织任务,那么跟踪任务可能会很麻烦。 这就是待办事项清单的帮助。 在这篇文章中,我将向您展示一些适用于Android的最佳免费待办事项列表应用程序。 然后,我将为您提供一些有关如何创建自己的待办事项列表应用程序的指导。

    待办事项列表应用程序可让您保持任务井井有条,并确保始终可以访问它们。 一个好的待办事项列表应用程序还应该在设备上显示通知,以使用户可以设置和查看提醒。

    适用于Android的最佳免费待办事项清单应用程序

    有许多Android待办事项列表应用程序,其中一些值得一试。 让我们看一些最好的。

    Microsoft待办事项:列表,任务和提醒

    微软待办事项

    Microsoft待办事项:Microsoft的清单,任务和提醒是可用于捕获待办任务的最高级应用程序之一。 UI是一流的,其界面易于访问。 它包含执行和维护任务所需的所有功能。

    主要特点:

    • 可让您与朋友和家人共享任务列表并进行计划
    • 具有智能建议算法,可从您的列表中推荐可能与当天相关的任务
    • 可以使用表情符号,炫彩主题,深色模式等功能自定义列表
    • 多功能待办事项清单,例如购物清单,提醒,便笺等。
    • 能够将最大25 MB的大文件附加到任务
    • 日常组织者
    • 允许您按主题或项目将列表分组在一起

    Google任务:任何任务,任何目标。 把事情做完

    Google任务

    Google的Google Tasks是Android上最受欢迎的待办事项列表应用程序之一。 它易于使用,并具有大量令人惊叹的功能。 它还与Gmail和Google日历集成,可帮助您更快地完成任务。 通过提醒您您的计划,这还将节省您的时间和精力。 该应用程序的其他功能包括:

    • 随着工作的进行,编辑有关任何任务的详细信息
    • 按日期整理任务或使用拖放功能确定优先级
    • 将您的任务分解为子任务

    滴答滴答

    刻度线

    如果您希望保持组织性和创造性, TickTick是理想的待办事项列表应用程序。 如果您总是错过任务的最后期限,则可以设置提醒并完全避免错过最后期限。 与大多数其他待办事项应用程序不同,TickTick提供了无限的空间来存储每个任务的注释。

    TickTick还通过允许基于用户的评论来促进协作,这些评论在与他人协作执行任务时会派上用场。

    其他主要功能包括:

    • 任务分为列表和文件夹,因此您可以拥有用于工作,家庭和业余爱好的不同文件夹
    • 简单的设计,让您轻松切换到各种任务
    • 优先安排任务
    • 向任务添加重复和位置提醒

    待办事项清单

    待办事项清单

    待办事项清单是一个非常简单明了的Android应用,具有非常易于使用的界面。 只有几个按钮,可以轻松创建,编辑和查看任何任务。

    主要功能包括:

    • 支持重复任务
    • 支持各种类型的任务,例如没有到期日期的任务,全天任务以及一天中特定时间的任务
    • 用户友好的任务管理系统
    • 智能主屏幕小部件向您显示下一步该做什么
    • Google同步

    托多斯

    托多斯

    Todoist也是Android上流行的待办事项清单应用程序。 该应用程序同时提供免费和高级版本。 Todoist免费版具有许多高级功能,例如添加新提醒的简便方法,主屏幕上的项目列表以及精巧的设计。

    主要功能包括:

    • 立即捕获和组织任务
    • 提醒可以帮助您记住截止日期和截止日期
    • 分配任务给其他人
    • 通过个性化的生产力趋势跟踪任务的进度
    • 优先处理任务的优先级

    使用Android应用程序模板创建待办事项列表应用程序

    应用程序模板是加快开发项目或学习如何创建应用程序的好方法。 模板也可以作为灵感来源! CodeCanyon是Android应用程序模板的全球最佳市场,拥有许多综合的入门模板,这些模板可以确保为您在待办事项Android应用程序上节省大量工作。

    通过下载应用模板,您可以轻松创建可以上传到Play商店的完整Android应用。 通过基于应用模板的专业设计和功能,您可以快速启动应用,并专注于使它与众不同的独特部分。

    这是待办事项列表应用程序的一些最佳模板。

    任务清单待办事项模板


    任务列表任务模板具有一个简单的任务列表编辑器,该编辑器具有提醒选项,可让您快速创建,编辑,删除或检查任务。 用户还可以创建列表并为列表设置图标。 您还可以在列表内创建其他项目。

    此应用程序模板的其他显着功能包括:

    • 漂亮的UI设计
    • 无限的任务和清单
    • 在小部件上显示任务
    • 设置列表图标
    • 可以将任务添加到特定日期
    • 可以自定义相机和照片库中的图标的功能
    • 文件存储在本地而不是服务器上
    • 离线工作

    MyTodo:待办事项列表颤振应用程序

    mydodo

    MyTodo是一个简单的应用程序,可帮助您跟踪所有任务列表,从简单的任务到更复杂的项目。 您所有的任务都组织在一个漂亮的界面中。 主要功能包括:

    • 轻松添加和删除任务的能力
    • 可以将任务归类
    • 使用颜色和图标个性化待办事项类别
    • 漂亮的设计

    使用API​​创建Android待办事项列表应用

    API使在移动应用程序和Web服务之间交换数据成为可能。

    构建应用程序时有两种选择:集成现有API或创建新API。 使用现有的API可以节省大量金钱和时间。 与现有的API集成可以减少您要做的编码,并使启动项目变得更加容易。 这样的API之一就是Todoist REST API。

    Todoist REST API

    Todoist API对于想要在其应用程序中添加Todoist功能的任何开发人员都是免费的。

    Todoist REST API允许开发人员以编程方式访问Todoist的大多数基本功能,以管理任务和项目。 使用此API,您可以创建一个Android应用,该应用允许用户创建重复任务,按项目组织任务,将任务分配给其他人等等。

    该API提供对以下工具的访问:

    • 能够添加,编辑和删除任务
    • 管理任务标签
    • 将您的想法分解成几个部分
    • 管理项目
    • 添加不同的配色方案

    结论

    在本文中,我们看到了一些最好的待办事项列表应用程序。 但是,您不必仅限于此列表中的应用程序。 您也可以自己制作并根据需要进行自定义! Android应用程序模板是入门的绝佳方法。

    CodeCanyon是一个在线市场,其中包含数百个其他专业的Android应用程序模板和构建器工具。 其中一些功能令人难以置信,并且经过精心设计。 通过使用其中之一,您有时可以节省几天甚至几个月的精力。

    翻译自: https://code.tutsplus.com/tutorials/the-best-to-do-list-app-for-android-that-you-can-make-yourself--cms-35048

    展开全文
  • 简单的待办事项-源码

    2021-02-14 16:46:14
    Simple ToDo是一个Android应用程序,它允许构建待办事项列表和基本的待办事项管理功能,包括添加新项目,编辑和删除现有项目。 提交者: Ashlee Kupor 花费时间:总共花费3个小时 用户故事 完成以下必需的功能: ...
  • Todo App是一个Android应用程序,它允许构建待办事项列表和基本的待办事项管理功能,包括添加新项目,编辑和删除现有项目。 提交人: Brayhan De Aza 花费时间:总共花费2个小时 用户故事 完成以下必需的功能: ...
  • 一个面向Android的简单,开放源代码“待办事项”应用程序,着重于简约性。 适用于Android 4.0.1及更高版本的GooglePlay免费提供。
  • Todo-List-Application:一个小型的Android应用,可保存您的日常待办事项
  • SQLite-Demo-App 这是一个演示应用程序,展示了...tns run android 贡献 叉子! 创建功能分支: git checkout -b my-new-feature 提交更改: git commit -am 'Add some feature' 推送到分支: git push origin m
  • 今天就通过一个关于待办事项的小例子来加深对于他们的理解。     一、需求分析 说明:   u 应用分为三个界面:待办清单页面,详情内容页面,添加页面 u 代办清单页面展示所有的代办清单内容 u 点击...

    我们都知道,在安卓开发中,ListView是非常重要且常用的一个控件,而SQLite也以其轻量型特性被大家广泛使用,因此,这二者在一起必定会擦出不一样的火花。

     

    今天就通过一个关于待办事项的小例子来加深对于他们的理解。

     

     

    一、需求分析

    说明:

     

    u  应用分为三个界面:待办清单页面,详情内容页面,添加页面

    u  代办清单页面展示所有的代办清单内容

    u  点击页面清单中一项,例如洗衣服,跳转到详细内容页面

    u  详细内容页面展示当前点击项的具体内容,点击返回按钮,返回代办清单页面

    u  在代办清单页面点击添加按钮,跳转到添加页面

    u  添加页面输入完成点击完成按钮,返回代办清单页面。点击完成时输入为空,提示请输入内容;点击返回时不保存当前页内容,返回待办清单页面

     

     

    二、界面设计

         1、 先设计出三个界面,代码如下:

                    (1)         代办清单页面:activity_main.xml

    
     
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity"
        android:orientation="vertical">
    
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
    
            android:gravity="center"
            android:text="代办清单"
            android:textSize="20dp"
            android:layout_gravity="center"
            android:background="@color/black"
            android:textColor="@color/white"
            android:paddingTop="10dp"
            android:paddingBottom="10dp"/>
        <ListView
            android:id="@+id/listView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1">
    
        </ListView>
        <Button
            android:id="@+id/add"
            android:layout_width="50dip"
            android:layout_height="50dip"
            android:layout_gravity="center"
            android:text="+"
            android:textSize="30dp"
            android:textColor="#969696"
            android:layout_marginBottom="30dp"
            android:background="@drawable/btn_circle">
        </Button>
    
    </LinearLayout>

                   (2)    详情内容页面:detail_xml

     

    
     

     

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:background="@color/black"
            android:layout_marginBottom="40dp">
    
            <Button
                android:id="@+id/back_detail"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="返回"
                android:textSize="20dp"
                android:background="@null"
                android:layout_weight="1"
                android:textColor="@color/white">
            </Button>
    
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="详细内容"
                android:textSize="20dp"
                android:gravity="center"
                android:layout_weight="1"
                android:textColor="@color/white">
            </TextView>
            <Button
                android:id="@+id/save_detail"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:text="保存"
                android:textSize="20dp"
                android:background="@null"
                android:layout_weight="1"
                android:textColor="@color/white">
            </Button>
    
        </LinearLayout>
    
        <EditText
            android:id="@+id/title_detail"
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:layout_marginTop="30dp"
            android:layout_marginBottom="10dp"
            android:layout_marginLeft="30dp"
            android:layout_marginRight="30dp"
            android:background="@drawable/edit_sharp"
            android:gravity="start">
        </EditText>
    
        <EditText
            android:id="@+id/context_detail"
            android:layout_width="match_parent"
            android:layout_height="200dp"
            android:layout_marginTop="30dp"
            android:layout_marginLeft="30dp"
            android:layout_marginRight="30dp"
            android:background="@drawable/edit_sharp"
            android:gravity="start">
        </EditText>
    
    </LinearLayout>

     

    (3)添加页面:add.xml

     

    
     
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:background="@color/black"
            android:layout_marginBottom="40dp">
    
            <Button
                android:id="@+id/back_add"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="返回"
                android:textSize="20dp"
                android:background="@null"
                android:layout_weight="1"
                android:textColor="@color/white">
            </Button>
    
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="添加事项"
                android:textSize="20dp"
                android:gravity="center"
                android:layout_weight="1"
                android:textColor="@color/white">
            </TextView>
            <Button
                android:id="@+id/finish"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:text="完成"
                android:textSize="20dp"
                android:background="@null"
                android:layout_weight="1"
                android:textColor="@color/white">
            </Button>
    
        </LinearLayout>
    
        <EditText
            android:id="@+id/title_add"
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:layout_marginTop="30dp"
            android:layout_marginBottom="10dp"
            android:layout_marginLeft="30dp"
            android:layout_marginRight="30dp"
            android:hint="请输入标题"
            android:background="@drawable/edit_sharp"
            android:gravity="top|left">
        </EditText>
    
        <EditText
            android:id="@+id/context_add"
            android:layout_width="match_parent"
            android:layout_height="200dp"
            android:layout_marginTop="30dp"
            android:layout_marginLeft="30dp"
            android:layout_marginRight="30dp"
            android:hint="请输入详细内容"
            android:background="@drawable/edit_sharp"
            android:gravity="top|left">
        </EditText>
    </LinearLayout>

     

    (4)对于ListView中的每一项,给他们附上每一件事项的id和title,因为id在事项列表中不呈现,所以设它的visibility=“gone”,

    item.xml如下:

     

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <TextView
            android:id="@+id/note_id"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="30dp"
            android:layout_marginRight="30dp"
            android:visibility="gone"/>
        <TextView
            android:id="@+id/note_title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="30dp"
            android:layout_marginRight="30dp"
            android:layout_marginTop="30dp"
            android:textStyle="bold"/>
    
    </LinearLayout>

    三、数据库操作

    1、为了能连接到数据库,建立一个DBHelper类,继承SQLiteOpenHelper,去实现对数据库的管理,主要有以下一些函数以及功能:

    但是在实际中,我们只在该类中实现自带的构造方法、onCreate()方法以及onUpgrade()方法

    DBHelper.java:

    package com.example.tttao.todo;
    
    import android.content.Context;
    import android.database.sqlite.SQLiteDatabase;
    import android.database.sqlite.SQLiteOpenHelper;
    
    public class DBHelper extends SQLiteOpenHelper {
        private static final int DATABASE_VERSION=4;
        private static final String DATABASE_NAME="todo.db";
        public DBHelper(Context context ) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }
    
        /**
         * 创建一个数据库,建表,只在第一次时调用
         * @param sqLiteDatabase
         */
        @Override
        public void onCreate(SQLiteDatabase sqLiteDatabase) {
            String sql="create table "+Note.TABLE+"("
                    +Note.KEY_id+" integer primary key autoincrement, "
                    +Note.KEY_title+" text, "
                    +Note.KEY_context+" text)";
            sqLiteDatabase.execSQL(sql);
        }
    
        /**
         * 作用:更新数据库表结构
         * 调用时机:数据库版本发生变化的时候回调(取决于数据库版本)
         * 创建SQLiteOpenHelper子类对象的时候,必须传入一个version参数
         //该参数就是当前数据库版本, 只要这个版本高于之前的版本, 就会触发这个onUpgrade()方法
         * @param sqLiteDatabase
         * @param i
         * @param i1
         */
        @Override
        public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
            sqLiteDatabase.execSQL("drop table if exists "+Note.TABLE);
            onCreate(sqLiteDatabase);
        }
    }
    

    2、在本应用中涉及到了待办事项的id,title和context,所以建立一个方法将他们封装起来,方便后面的使用

    Note.java

    package com.example.tttao.todo;
    
    public class Note {
        //表名
        public static final String TABLE = "todo";
        //列名
        public static final String KEY_id="id";
        public static final String KEY_title="title";
        public static final String KEY_context="context";
    
        public int note_id;
        public String title;
        public String context;
    }
    

    3、建立一个操作类,实现对数据库的增删改查操作

    NoteOperator.java:

    package com.example.tttao.todo;
    
    import android.content.ContentValues;
    import android.content.Context;
    import android.database.Cursor;
    import android.database.sqlite.SQLiteDatabase;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    
    public class NoteOperator {
        private DBHelper dbHelper;
    
        public NoteOperator(Context context){
    
            dbHelper=new DBHelper(context);
        }
    
        /**
         * 插入数据
         * @param note
         * @return
         */
        public boolean insert(Note note){
            //与数据库建立连接
            SQLiteDatabase db=dbHelper.getWritableDatabase();
            ContentValues contentValues=new ContentValues();
            contentValues.put(Note.KEY_title,note.title);
            contentValues.put(Note.KEY_context,note.context);
            //插入每一行数据
            long note_id=db.insert(Note.TABLE,null,contentValues);
            db.close();
            if(note_id!=-1)
                return true;
            else
                return false;
        }
    
        /**
         * 删除数据
         * @param note_id
         */
        public void delete(int note_id){
            //与数据库建立连接
            SQLiteDatabase db=dbHelper.getWritableDatabase();
            db.delete(Note.TABLE,Note.KEY_id+"=?",new String[]{String.valueOf(note_id)});
            db.close();
        }
    
        /**
         * 从数据库中查找 id,title,context
         * @return ArrayList
         */
        public ArrayList<HashMap<String,String>> getNoteList(){
            //与数据库建立连接
            SQLiteDatabase db=dbHelper.getReadableDatabase();
            String sql="select "+Note.KEY_id+","+Note.KEY_title+","+Note.KEY_context+
                    " from "+Note.TABLE;
            //通过游标将每一条数据放进ArrayList中
            ArrayList<HashMap<String,String>> noteList=new ArrayList<HashMap<String,String>>();
            Cursor cursor=db.rawQuery(sql,null);
            while (cursor.moveToNext()){
                    HashMap<String,String> note=new HashMap<String,String>();
                    note.put("id",cursor.getString(cursor.getColumnIndex(Note.KEY_id)));
                    note.put("title",cursor.getString(cursor.getColumnIndex(Note.KEY_title)));
                    noteList.add(note);
            }
            cursor.close();
            db.close();
            return noteList;
        }
    
        /**
         * 通过id查找,返回一个Note对象
         * @param id
         * @return
         */
        public Note getNoteById(int id){
            //与数据库建立连接
            SQLiteDatabase db=dbHelper.getReadableDatabase();
            String sql="select "+Note.KEY_title+","+Note.KEY_context+
                    " from "+Note.TABLE+" where "+Note.KEY_id+"=?";
            Note note=new Note();
            Cursor cursor=db.rawQuery(sql,new String[]{String.valueOf(id)});
            while(cursor.moveToNext()) {
                    note.title = cursor.getString(cursor.getColumnIndex(Note.KEY_title));
                    note.context = cursor.getString(cursor.getColumnIndex(Note.KEY_context));
            }
            cursor.close();
            db.close();
            return note;
        }
    
        /**
         * 更新数据
         * @param note
         */
        public void update(Note note){
            SQLiteDatabase db=dbHelper.getWritableDatabase();
            ContentValues contentValues=new ContentValues();
    
            contentValues.put(Note.KEY_title,note.title);
            contentValues.put(Note.KEY_context,note.context);
    
            db.update(Note.TABLE,contentValues,Note.KEY_id+"=?",new String[]{String.valueOf(note.note_id)});
            db.close();
        }

     

    四、实现功能

    1、点击“添加”按钮,跳到添加页面(AddActivity.java)

    给add按钮设置一个监听事件,通过intent实现跳转:

    @Override
        public void onClick(View view) {
            Intent intent = new Intent();
            intent.setClass(MainActivity.this, AddActivity.class);
            MainActivity.this.startActivity(intent);
        }

    2、添加之后,点击完成可以跳回待办界面,listView中值进行刷新:

    public void onClick(View view) {
    
            if (view == findViewById(R.id.finish)) {
                NoteOperator noteOperator = new NoteOperator(AddActivity.this);
                get_title = title.getText().toString().trim();
                get_context = context.getText().toString().trim();
    
                if (TextUtils.isEmpty(get_title) || TextUtils.isEmpty(get_context)) {
                    Toast.makeText(AddActivity.this, "添加信息不能为空", Toast.LENGTH_SHORT).show();
                } else {
                    Note note = new Note();
                    note.title = get_title;
                    note.context = get_context;
                    boolean add = noteOperator.insert(note);
                    //如果添加数据成功,跳到待办事项界面,并通过传值,让目标界面进行刷新
                    if (add) {
                        //Toast.makeText(AddActivity.this,"添加成功",Toast.LENGTH_SHORT).show();
                        Intent intent = new Intent();
                        intent.setClass(AddActivity.this, MainActivity.class);
                        intent.putExtra("Insert", 1);
                        startActivity(intent);
                    } else {
                        Toast.makeText(AddActivity.this, "添加失败", Toast.LENGTH_SHORT).show();
                    }
                }
            } else if (view == findViewById(R.id.back_add)) {
                Intent intent = new Intent(AddActivity.this, MainActivity.class);
                startActivity(intent);
            }

    3、MainActivity.java中通过listAdapter对listView赋值:

    //通过list获取数据库表中的所有id和title,通过ListAdapter给listView赋值
            final NoteOperator noteOperator = new NoteOperator(MainActivity.this);
            list = noteOperator.getNoteList();
            final ListAdapter listAdapter = new SimpleAdapter(MainActivity.this, list, R.layout.item,
                    new String[]{"id", "title"}, new int[]{R.id.note_id, R.id.note_title});
            listView.setAdapter(listAdapter);
    
            //通过添加界面传来的值判断是否要刷新listView
            Intent intent = getIntent();
            int flag = intent.getIntExtra("Insert", 0);
            if (flag == 1) {
                list = noteOperator.getNoteList();
                listView.setAdapter(listAdapter);
            }

    4、点击待办事项中的任何一项,可以跳到详情页面查看详情,这时需要给listView设置一个点击事件(通过intent将id传递给DetailActivity.java,然后目标页面再通过接收到的id进行查找title和context,并显示出来):

    //点击listView的任何一项跳到详情页面
                listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                    @Override
                    public void onItemClick(AdapterView<?> adapterView, View view, int position, long i) {
    
                        String id = list.get(position).get("id");
                        Intent intent = new Intent();
                        intent.setClass(MainActivity.this, DetailActivity.class);
                        intent.putExtra("note_id", Integer.parseInt(id));
                        startActivity(intent);
                    }
                });

    5、DetailActivity.java(详情页面)接收到上一个页面点击传来的id,通过数据库查找操作,找到该事项的title和context,并在editText中显示出来:

    //接收listView中点击item传来的note_id,
            Intent intent=getIntent();
            note_id=intent.getIntExtra("note_id",0);
            NoteOperator noteOperator=new NoteOperator( this);
            Note note = noteOperator.getNoteById(note_id);
    
            title.setText(String.valueOf(note.title));
            context.setText(String.valueOf(note.context));

    6、DetailActivity.java(详情页面)不仅可以展示每一项的详细内容,还可以对内容进行编辑,保存。点击保存之后跳到待办事项界面:

    if(view == findViewById(R.id.save_detail)){
                get_title=title.getText().toString().trim();
                get_context=context.getText().toString().trim();
                if(TextUtils.isEmpty(get_title)||TextUtils.isEmpty(get_context)){
                    Toast.makeText(this,"修改内容不能为空",Toast.LENGTH_SHORT).show();
                }else{
                    Note note=new Note();
                    note.note_id=note_id;
                    note.title=get_title;
                    note.context=get_context;
                    NoteOperator noteOperator=new NoteOperator(DetailActivity.this);
                    noteOperator.update(note);
    
                    Toast.makeText(this,"修改成功",Toast.LENGTH_SHORT).show();
                    Intent intent=new Intent();
                    intent.setClass(DetailActivity.this,MainActivity.class);
                    startActivity(intent);
    
                }
            }

    7、待办事项页面中listView长按可以实现列表数据的删除:

    listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
                    @Override
                    public boolean onItemLongClick(final AdapterView<?> adapterView, View view, final int position, long l) {
                        AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
                        builder.setMessage("确定删除?");
                        builder.setTitle("提示");
    
                        //添加AlterDialog.Builder对象的setPositiveButton()方法
                        builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialogInterface, int which) {
                                String id = list.get(position).get("id");
                                noteOperator.delete(Integer.parseInt(id));
                                list.remove(position);
                                //listAdapter.notify();
                                listView.setAdapter(listAdapter);
                            }
                        });
    
                        //添加AlterDialog.Builder对象的setNegativeButton()方法
                        builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialogInterface, int i) {
    
                            }
                        });
                        builder.create().show();
                        return true;
                    }
                });

    五、测试结果

    1、进入界面:

    2、添加事项:

    3、待办事项中加入了一条数据:

    4、点击查看详情并修改:

    5、长按可以修改列表数据:

    源码地址:https://gitee.com/laymmy/todo

    欢迎大家多多批评指正,手动比心~~

    展开全文
  • Todo是一个Android应用程序,它允许构建待办事项列表和基本的待办事项管理功能,包括添加新项目,编辑和删除现有项目。 提交人:Trinity 花费时间:总共花费4个小时 用户故事 完成以下必需的功能: 用户可以查看...
  • 待办事项提醒软件

    2014-04-01 16:20:31
    一个可以记录待办事项的软件,包括服务器端,客户端,数据库,服务器端使用C#编写,客户端为Android,数据库为SQL Server
  • 待办事项列表应用程序 •此待办事项列表应用程序使用Firebase身份验证进行用户注册和登录。 •它允许用户添加和更新带有标题,详细信息和时间的任务。 •所有数据都存储在Firebase实时数据库中。 •UI精心设计,带有...
  • 我的应用程序是一个Android应用程序,它允许构建待办事项列表和基本的待办事项管理功能,包括添加新项目,编辑和删除现有项目。 提交人:Zavion Harris-Smart 花费时间:总共花费5个小时 用户故事 完成以下必需的...
  • VOXE是一个简单的概念验证待办事项应用程序,适用于Android,iOS,Web和使用Google上的 , 和构建的Google Assistant。 该存储库包含: 可以编译为Android,iOS和Web的NativeScript(Angular)应用 Dialogflow代理...

空空如也

空空如也

1 2 3 4 5 ... 15
收藏数 285
精华内容 114
关键字:

android待办事项