├── .gitignore ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro ├── release │ ├── app-release.apk │ └── output.json └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── example │ │ └── habittest │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── example │ │ │ └── habittest │ │ │ ├── AboutUs.java │ │ │ ├── AddHabit.java │ │ │ ├── CalendarReminderUtils.java │ │ │ ├── DBManager.java │ │ │ ├── Fragment1.java │ │ │ ├── Fragment2.java │ │ │ ├── Fragment3.java │ │ │ ├── Habit.java │ │ │ ├── HabitListItem.java │ │ │ ├── HabitListItemAdapter.java │ │ │ ├── HabitLog.java │ │ │ ├── HelpLayout.java │ │ │ ├── MainActivity.java │ │ │ ├── MySqliteHelper.java │ │ │ ├── OverHabit.java │ │ │ ├── TodayCard.java │ │ │ └── Utils.java │ └── res │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ ├── card.jpg │ │ ├── card_1.jpg │ │ ├── card_2.jpg │ │ ├── card_3.jpg │ │ ├── card_4.jpg │ │ ├── card_5.jpg │ │ ├── card_6.jpg │ │ ├── const_edge.xml │ │ ├── habit_1.png │ │ ├── habit_1_gray.png │ │ ├── habit_2.png │ │ ├── habit_2_gray.png │ │ ├── habit_3.png │ │ ├── habit_3_gray.png │ │ ├── habit_4.png │ │ ├── habit_4_gray.png │ │ ├── habit_5.png │ │ ├── habit_5_gray.png │ │ ├── habit_6.png │ │ ├── ic_about_us.png │ │ ├── ic_all_normal.png │ │ ├── ic_all_select.png │ │ ├── ic_card.png │ │ ├── ic_dashboard_black_24dp.xml │ │ ├── ic_help.png │ │ ├── ic_home_1_normal.png │ │ ├── ic_home_1_select.png │ │ ├── ic_home_black_24dp.xml │ │ ├── ic_launcher_background.xml │ │ ├── ic_menu_share.png │ │ ├── ic_more_normal.png │ │ ├── ic_more_select.png │ │ ├── ic_notifications_black_24dp.xml │ │ ├── ic_over.png │ │ ├── ic_share.png │ │ ├── ic_sina.png │ │ ├── logo.png │ │ ├── plus.png │ │ ├── pure.xml │ │ ├── select.xml │ │ ├── shadow_date.xml │ │ ├── shape.xml │ │ ├── shape_1.xml │ │ ├── shape_1_selected.xml │ │ ├── shape_2.xml │ │ ├── shape_2_selected.xml │ │ ├── shape_finish.xml │ │ ├── shape_mine.xml │ │ ├── shape_selected.xml │ │ ├── shape_time.xml │ │ ├── sign_point.xml │ │ └── social_qq.png │ │ ├── layout │ │ ├── activity_about_us.xml │ │ ├── activity_add_habit.xml │ │ ├── activity_habit_log.xml │ │ ├── activity_main.xml │ │ ├── activity_over_habit.xml │ │ ├── activity_today_card.xml │ │ ├── all_habits.xml │ │ ├── date_item.xml │ │ ├── grid_item.xml │ │ ├── habit_grid.xml │ │ ├── habit_list_item.xml │ │ ├── help.xml │ │ └── mine.xml │ │ ├── menu │ │ └── navigation.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_check_white.png │ │ ├── ic_launcher.png │ │ ├── ic_launcher_round.png │ │ └── md_nav_back.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_round.png │ │ └── icon_back_arrow.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ │ └── xml │ │ └── file_paths.xml │ └── test │ └── java │ └── com │ └── example │ └── habittest │ └── ExampleUnitTest.java ├── build.gradle ├── example ├── 1.jpg ├── 2.jpg ├── 3.jpg ├── 4.jpg ├── 5.jpg └── 6.jpg ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/caches/build_file_checksums.ser 5 | /.idea/libraries 6 | /.idea/modules.xml 7 | /.idea/workspace.xml 8 | .DS_Store 9 | /build 10 | /captures 11 | .externalNativeBuild 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # HabitDeveloping 2 | 一款习惯养成app,包含设定习惯目标、打卡、习惯提醒、今日卡片等功能。 3 | 4 | ## 说明 5 | - 系统:Android 8.1以上 6 | - 分辨率:2340 * 1080 7 | 8 | 你可以[点击此处](https://github.com/a925722655/HabitDeveloping/raw/master/app/release/app-release.apk)下载apk安装 9 | 10 | ## 界面 11 | 今日习惯 12 | 13 | 14 | 15 | 添加习惯 16 | 17 | 18 | 19 | 全部习惯 20 | 21 | 22 | 23 | 习惯详情 24 | 25 | 26 | 27 | 关于 28 | 29 | 30 | 31 | 今日卡片 32 | 33 | 34 | 35 | 36 | 第一次写Android,代码不够优雅,有很多硬编码,还有一些小bug。 37 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 27 5 | aaptOptions.cruncherEnabled = false 6 | aaptOptions.useNewCruncher = false 7 | defaultConfig { 8 | applicationId "com.example.habittest" 9 | minSdkVersion 26 10 | targetSdkVersion 27 11 | versionCode 1 12 | versionName "1.0" 13 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 14 | } 15 | buildTypes { 16 | release { 17 | minifyEnabled false 18 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 19 | } 20 | } 21 | 22 | } 23 | 24 | dependencies { 25 | implementation fileTree(include: ['*.jar'], dir: 'libs') 26 | implementation 'com.android.support:appcompat-v7:27.1.1' 27 | implementation 'com.android.support:design:27.1.1' 28 | implementation 'com.android.support.constraint:constraint-layout:1.1.3' 29 | testImplementation 'junit:junit:4.12' 30 | androidTestImplementation 'com.android.support.test:runner:1.0.2' 31 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' 32 | 33 | // jsoup HTML parser library @ https://jsoup.org/ 34 | implementation 'org.jsoup:jsoup:1.12.1' 35 | 36 | implementation 'com.contrarywind:Android-PickerView:4.1.8' 37 | } 38 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /app/release/app-release.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a9257/HabitDeveloping/2d913f1673dba1aa627ef2d4b1a6e19b35a6ca3d/app/release/app-release.apk -------------------------------------------------------------------------------- /app/release/output.json: -------------------------------------------------------------------------------- 1 | [{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":1,"versionName":"1.0","enabled":true,"outputFile":"app-release.apk","fullName":"release","baseName":"release"},"path":"app-release.apk","properties":{}}] -------------------------------------------------------------------------------- /app/src/androidTest/java/com/example/habittest/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.example.habittest; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumented test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.example.habittest", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 20 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 40 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/habittest/AboutUs.java: -------------------------------------------------------------------------------- 1 | package com.example.habittest; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.content.pm.ApplicationInfo; 6 | import android.content.pm.PackageManager; 7 | import android.net.Uri; 8 | import android.support.v7.app.AppCompatActivity; 9 | import android.os.Bundle; 10 | import android.view.View; 11 | import android.widget.Toast; 12 | 13 | public class AboutUs extends AppCompatActivity { 14 | 15 | @Override 16 | protected void onCreate(Bundle savedInstanceState) { 17 | super.onCreate(savedInstanceState); 18 | setContentView(R.layout.activity_about_us); 19 | 20 | android.support.v7.widget.Toolbar toolbar = (android.support.v7.widget.Toolbar) findViewById(R.id.toolbar5); 21 | toolbar.setNavigationOnClickListener(new View.OnClickListener() { 22 | @Override 23 | public void onClick(View view) { 24 | finish(); 25 | } 26 | }); 27 | 28 | } 29 | 30 | // 跳转至微博个人页 31 | public void jumpToWeiboProfileInfo(Context context, String uid) { 32 | Intent intent = new Intent(Intent.ACTION_VIEW); 33 | intent.addCategory(Intent.CATEGORY_DEFAULT); 34 | intent.addCategory(Intent.CATEGORY_BROWSABLE); 35 | boolean weiboInstalled = Utils.isSinaWeiboInstalled(context); 36 | if (weiboInstalled) { 37 | intent.setData(Uri.parse("sinaweibo://userinfo?uid=" + uid)); 38 | } else { 39 | intent.setData(Uri.parse("http://weibo.cn/qr/userinfo?uid=" + uid)); 40 | } 41 | context.startActivity(intent); 42 | } 43 | 44 | public void weibo(View v) { 45 | jumpToWeiboProfileInfo(this, "2102377183"); 46 | } 47 | 48 | public void jumptoQQ(View view) { 49 | String qqnum = "982728182"; 50 | if (checkApkExist(this, "com.tencent.mobileqq")) { 51 | startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("mqqwpa://im/chat?chat_type=wpa&uin=" + qqnum + "&version=1"))); 52 | } else { 53 | Toast.makeText(this, "本机未安装QQ应用", Toast.LENGTH_SHORT).show(); 54 | } 55 | } 56 | 57 | public boolean checkApkExist(Context context, String packageName) { 58 | if (packageName == null || "".equals(packageName)) 59 | return false; 60 | try { 61 | ApplicationInfo info = context.getPackageManager().getApplicationInfo(packageName, 62 | PackageManager.GET_UNINSTALLED_PACKAGES); 63 | return true; 64 | } catch (PackageManager.NameNotFoundException e) { 65 | return false; 66 | } 67 | } 68 | 69 | 70 | } 71 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/habittest/AddHabit.java: -------------------------------------------------------------------------------- 1 | package com.example.habittest; 2 | 3 | import android.database.sqlite.SQLiteDatabase; 4 | import android.support.v7.app.AppCompatActivity; 5 | import android.os.Bundle; 6 | import android.view.View; 7 | import android.widget.Button; 8 | import android.widget.EditText; 9 | import android.widget.ImageView; 10 | import android.widget.RadioGroup; 11 | import android.widget.TextView; 12 | import android.support.v7.widget.Toolbar; 13 | import android.widget.Toast; 14 | 15 | 16 | import com.bigkoo.pickerview.builder.TimePickerBuilder; 17 | import com.bigkoo.pickerview.listener.OnTimeSelectListener; 18 | import com.bigkoo.pickerview.view.TimePickerView; 19 | 20 | import java.util.Calendar; 21 | import java.util.Date; 22 | 23 | public class AddHabit extends AppCompatActivity { 24 | 25 | private ImageView imageView; 26 | private Button[] bt = new Button[4]; 27 | private Button[] bt2 = new Button[3]; 28 | private String[] t = {"任意时间", "晨间习惯", "午间习惯", "晚间习惯"}; 29 | private String[] f = {"每日", "每周", "每月"}; 30 | 31 | private String img; 32 | private String time; 33 | private String frequency; 34 | private String strHour = ""; 35 | private String strMin = ""; 36 | 37 | //数据库相关变量 38 | private MySqliteHelper helper; 39 | private SQLiteDatabase db; 40 | private DBManager mgr; 41 | 42 | @Override 43 | protected void onCreate(Bundle savedInstanceState) { 44 | super.onCreate(savedInstanceState); 45 | setContentView(R.layout.activity_add_habit); 46 | final String[] imgName = {"habit_1", "habit_2", "habit_3", "habit_4", "habit_5"}; 47 | 48 | //数据库变量初始化 49 | helper = DBManager.getIntance(this); 50 | db = helper.getWritableDatabase();//创建或打开数据库 51 | mgr = new DBManager(db); 52 | 53 | //返回事件 54 | Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar2); 55 | toolbar.setNavigationOnClickListener(new View.OnClickListener() { 56 | @Override 57 | public void onClick(View view) { 58 | finish(); 59 | } 60 | }); 61 | 62 | bt[0] = (Button) findViewById(R.id.button); 63 | bt[1] = (Button) findViewById(R.id.morning); 64 | bt[2] = (Button) findViewById(R.id.noon); 65 | bt[3] = (Button) findViewById(R.id.button4); 66 | 67 | bt2[0] = (Button) findViewById(R.id.button5); 68 | bt2[1] = (Button) findViewById(R.id.button6); 69 | bt2[2] = (Button) findViewById(R.id.button7); 70 | 71 | 72 | //设置初始选择任意时间 73 | selectTime(0); 74 | //设置初始选择每天 75 | selectFre(0); 76 | 77 | //选择图标事件 78 | RadioGroup rg = (RadioGroup) findViewById(R.id.radioGroup); 79 | imageView = (ImageView) findViewById(R.id.habit_img); 80 | 81 | //设置初始图标 82 | img = imgName[0]; 83 | rg.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() { 84 | @Override 85 | public void onCheckedChanged(RadioGroup group, int checkedId) { 86 | switch (checkedId) { 87 | case R.id.img1: 88 | imageView.setImageResource(getResources().getIdentifier(imgName[0], "drawable", getPackageName())); 89 | img = imgName[0]; 90 | break; 91 | case R.id.img2: 92 | imageView.setImageResource(getResources().getIdentifier(imgName[1], "drawable", getPackageName())); 93 | img = imgName[1]; 94 | break; 95 | case R.id.img3: 96 | imageView.setImageResource(getResources().getIdentifier(imgName[2], "drawable", getPackageName())); 97 | img = imgName[2]; 98 | break; 99 | case R.id.img4: 100 | imageView.setImageResource(getResources().getIdentifier(imgName[3], "drawable", getPackageName())); 101 | img = imgName[3]; 102 | break; 103 | case R.id.img5: 104 | imageView.setImageResource(getResources().getIdentifier(imgName[4], "drawable", getPackageName())); 105 | img = imgName[4]; 106 | break; 107 | } 108 | } 109 | }); 110 | 111 | //时间选择器 112 | final TimePickerView pvTime = new TimePickerBuilder(AddHabit.this, new OnTimeSelectListener() { 113 | @Override 114 | public void onTimeSelect(Date date, View v) { 115 | Calendar cal = Calendar.getInstance(); 116 | cal.setTime(date); 117 | // Toast.makeText(AddHabit.this, cal.get(Calendar.HOUR_OF_DAY) + "" + cal.get(Calendar.MINUTE), Toast.LENGTH_SHORT).show(); 118 | EditText et = (EditText) findViewById(R.id.editText3); 119 | strHour = String.format("%02d", cal.get(Calendar.HOUR_OF_DAY)); 120 | strMin = String.format("%02d", cal.get(Calendar.MINUTE)); 121 | et.setText(strHour + " : " + strMin); 122 | } 123 | }).setType(new boolean[]{false, false, false, true, true, false}) 124 | .setTitleText("设置提醒时间") 125 | .isCyclic(true) 126 | .build(); 127 | 128 | findViewById(R.id.editText3).setOnClickListener(new View.OnClickListener() { 129 | @Override 130 | public void onClick(View v) { 131 | pvTime.show(); 132 | } 133 | }); 134 | 135 | 136 | } 137 | 138 | public void selectTime(int k) { 139 | for (int i = 0; i < 4; i++) { 140 | if (i == k) { 141 | bt[i].setTextColor(getResources().getColor(R.color.white)); 142 | bt[i].setBackgroundResource(R.drawable.shape_selected); 143 | } else { 144 | bt[i].setTextColor(getResources().getColor(R.color.black)); 145 | bt[i].setBackgroundResource(R.drawable.shape); 146 | } 147 | } 148 | time = t[k]; 149 | } 150 | 151 | public void time1(View view) { 152 | selectTime(0); 153 | } 154 | 155 | public void time2(View view) { 156 | selectTime(1); 157 | } 158 | 159 | public void time3(View view) { 160 | selectTime(2); 161 | } 162 | 163 | public void time4(View view) { 164 | selectTime(3); 165 | } 166 | 167 | public void selectFre(int k) { 168 | for (int i = 0; i < 3; i++) { 169 | if (i == k) { 170 | bt2[i].setTextColor(getResources().getColor(R.color.white)); 171 | bt2[i].setBackgroundResource(R.drawable.shape_2_selected); 172 | } else { 173 | bt2[i].setTextColor(getResources().getColor(R.color.bg_color)); 174 | bt2[i].setBackgroundResource(R.drawable.shape_2); 175 | } 176 | } 177 | frequency = f[k]; 178 | TextView textView = (TextView) findViewById(R.id.textView5); 179 | textView.setText(f[k]); 180 | } 181 | 182 | public void fre1(View view) { 183 | selectFre(0); 184 | } 185 | 186 | public void fre2(View view) { 187 | selectFre(1); 188 | } 189 | 190 | public void fre3(View view) { 191 | selectFre(2); 192 | } 193 | 194 | //获取时间的函数 195 | //获取当天零点的时间 196 | public long get_zero_time() { 197 | Calendar calendar = Calendar.getInstance(); 198 | calendar.set(Calendar.HOUR_OF_DAY, 0); 199 | calendar.set(Calendar.MINUTE, 0); 200 | calendar.set(Calendar.SECOND, 0); 201 | calendar.set(Calendar.MILLISECOND, 0); 202 | //当天0点 203 | long zero = calendar.getTimeInMillis(); 204 | return zero; 205 | } 206 | 207 | //根据小时、分钟、习惯名称设置提醒 208 | public void set_date_notice(String habit_name, String htext, int hour_time, int minute_time) { 209 | long zero = get_zero_time(); 210 | long extra_msec = 1000 * (hour_time * 60 + minute_time) * 60 + zero; 211 | CalendarReminderUtils.addCalendarEvent(this, habit_name, htext, extra_msec, 0); 212 | } 213 | 214 | //创建习惯事件 215 | public void addaHabit(View view) { 216 | //获取输入框 217 | EditText etName = (EditText) findViewById(R.id.editText); 218 | EditText etNum = (EditText) findViewById(R.id.editText2); 219 | // EditText etHour = (EditText) findViewById(R.id.editText3); 220 | // EditText etMin = (EditText) findViewById(R.id.editText4); 221 | EditText etText = (EditText) findViewById(R.id.editText5); 222 | //获取输入值 223 | String name = etName.getText().toString(); 224 | String strNum = etNum.getText().toString(); 225 | // String strHour = etHour.getText().toString(); 226 | // String strMin = etMin.getText().toString(); 227 | String htext = etText.getText().toString(); 228 | 229 | int num, hour, min; 230 | 231 | if (name.equals("")) { 232 | Toast.makeText(this, "习惯名不能为空", Toast.LENGTH_SHORT).show(); 233 | return; 234 | } 235 | if (strNum.equals("")) { 236 | Toast.makeText(this, "打卡次数不能为空", Toast.LENGTH_SHORT).show(); 237 | return; 238 | } 239 | num = Integer.parseInt(strNum); 240 | if (htext.equals("")) { 241 | htext = "只有千锤百炼,才能成为好钢。"; 242 | } 243 | if (strHour.equals("") && strMin.equals("")) { 244 | Date date = new Date(); 245 | Habit habit = new Habit(name, img, num, 0, time, frequency, htext, 0, 0, 0, Utils.date2String(date), 1); 246 | if (mgr.insertHabitDB(habit)) { 247 | finish(); 248 | return; 249 | } else { 250 | Toast.makeText(this, "习惯名不能重复", Toast.LENGTH_SHORT).show(); 251 | return; 252 | } 253 | } 254 | if ((!strHour.equals("")) && (!strMin.equals(""))) { 255 | hour = Integer.parseInt(strHour); 256 | min = Integer.parseInt(strMin); 257 | if (hour < 24 && hour >= 0 && min >= 0 && min < 60) { 258 | Date date = new Date(); 259 | Habit habit = new Habit(name, img, num, 0, time, frequency, htext, 0, 0, 0, Utils.date2String(date), 1); 260 | if (mgr.insertHabitDB(habit)) { 261 | set_date_notice(name, htext, hour, min); 262 | finish(); 263 | return; 264 | } else { 265 | Toast.makeText(this, "习惯名不能重复", Toast.LENGTH_SHORT).show(); 266 | return; 267 | } 268 | } else { 269 | Toast.makeText(this, "确保提醒时间设置正确", Toast.LENGTH_SHORT).show(); 270 | return; 271 | } 272 | } 273 | Toast.makeText(this, "确保提醒时间设置正确", Toast.LENGTH_SHORT).show(); 274 | } 275 | 276 | 277 | } 278 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/habittest/CalendarReminderUtils.java: -------------------------------------------------------------------------------- 1 | package com.example.habittest; 2 | 3 | import android.content.ContentUris; 4 | import android.content.ContentValues; 5 | import android.content.Context; 6 | import android.database.Cursor; 7 | import android.graphics.Color; 8 | import android.net.Uri; 9 | import android.os.Build; 10 | import android.provider.CalendarContract; 11 | import android.support.annotation.RequiresApi; 12 | import android.text.TextUtils; 13 | 14 | import java.util.Calendar; 15 | import java.util.TimeZone; 16 | 17 | 18 | 19 | public class CalendarReminderUtils { 20 | private static String CALENDER_URL = "content://com.android.calendar/calendars"; 21 | private static String CALENDER_EVENT_URL = "content://com.android.calendar/events"; 22 | private static String CALENDER_REMINDER_URL = "content://com.android.calendar/reminders"; 23 | 24 | private static String CALENDARS_NAME = "boohee"; 25 | private static String CALENDARS_ACCOUNT_NAME = "BOOHEE@boohee.com"; 26 | private static String CALENDARS_ACCOUNT_TYPE = "com.android.boohee"; 27 | private static String CALENDARS_DISPLAY_NAME = "BOOHEE账户"; 28 | 29 | /** 30 | * 检查是否已经添加了日历账户,如果没有添加先添加一个日历账户再查询 31 | * 获取账户成功返回账户id,否则返回-1 32 | */ 33 | @RequiresApi(api = Build.VERSION_CODES.N) 34 | private static int checkAndAddCalendarAccount(Context context) { 35 | int oldId = checkCalendarAccount(context); 36 | if( oldId >= 0 ){ 37 | return oldId; 38 | }else{ 39 | long addId = addCalendarAccount(context); 40 | if (addId >= 0) { 41 | return checkCalendarAccount(context); 42 | } else { 43 | return -1; 44 | } 45 | } 46 | } 47 | 48 | /** 49 | * 检查是否存在现有账户,存在则返回账户id,否则返回-1 50 | */ 51 | private static int checkCalendarAccount(Context context) { 52 | Cursor userCursor = context.getContentResolver().query(Uri.parse(CALENDER_URL), null, null, null, null); 53 | try { 54 | if (userCursor == null) { //查询返回空值 55 | return -1; 56 | } 57 | int count = userCursor.getCount(); 58 | if (count > 0) { //存在现有账户,取第一个账户的id返回 59 | userCursor.moveToFirst(); 60 | return userCursor.getInt(userCursor.getColumnIndex(CalendarContract.Calendars._ID)); 61 | } else { 62 | return -1; 63 | } 64 | } finally { 65 | if (userCursor != null) { 66 | userCursor.close(); 67 | } 68 | } 69 | } 70 | 71 | /** 72 | * 添加日历账户,账户创建成功则返回账户id,否则返回-1 73 | */ 74 | 75 | private static long addCalendarAccount(Context context) { 76 | TimeZone timeZone = TimeZone.getDefault(); 77 | ContentValues value = new ContentValues(); 78 | value.put(CalendarContract.Calendars.NAME, CALENDARS_NAME); 79 | value.put(CalendarContract.Calendars.ACCOUNT_NAME, CALENDARS_ACCOUNT_NAME); 80 | value.put(CalendarContract.Calendars.ACCOUNT_TYPE, CALENDARS_ACCOUNT_TYPE); 81 | value.put(CalendarContract.Calendars.CALENDAR_DISPLAY_NAME, CALENDARS_DISPLAY_NAME); 82 | value.put(CalendarContract.Calendars.VISIBLE, 1); 83 | value.put(CalendarContract.Calendars.CALENDAR_COLOR, Color.BLUE); 84 | value.put(CalendarContract.Calendars.CALENDAR_ACCESS_LEVEL, CalendarContract.Calendars.CAL_ACCESS_OWNER); 85 | value.put(CalendarContract.Calendars.SYNC_EVENTS, 1); 86 | value.put(CalendarContract.Calendars.CALENDAR_TIME_ZONE, timeZone.getID()); 87 | value.put(CalendarContract.Calendars.OWNER_ACCOUNT, CALENDARS_ACCOUNT_NAME); 88 | value.put(CalendarContract.Calendars.CAN_ORGANIZER_RESPOND, 0); 89 | 90 | Uri calendarUri = Uri.parse(CALENDER_URL); 91 | calendarUri = calendarUri.buildUpon() 92 | .appendQueryParameter(CalendarContract.CALLER_IS_SYNCADAPTER, "true") 93 | .appendQueryParameter(CalendarContract.Calendars.ACCOUNT_NAME, CALENDARS_ACCOUNT_NAME) 94 | .appendQueryParameter(CalendarContract.Calendars.ACCOUNT_TYPE, CALENDARS_ACCOUNT_TYPE) 95 | .build(); 96 | 97 | Uri result = context.getContentResolver().insert(calendarUri, value); 98 | long id = result == null ? -1 : ContentUris.parseId(result); 99 | return id; 100 | } 101 | 102 | /** 103 | * 添加日历事件 104 | */ 105 | @RequiresApi(api = Build.VERSION_CODES.N) 106 | public static void addCalendarEvent(Context context, String title, String description, long reminderTime, int previousDate) 107 | { 108 | if (context == null) 109 | { 110 | return; 111 | } 112 | int calId = checkAndAddCalendarAccount(context); //获取日历账户的id 113 | if (calId < 0) 114 | { //获取账户id失败直接返回,添加日历事件失败 115 | return; 116 | } 117 | 118 | //添加日历事件 119 | Calendar mCalendar = Calendar.getInstance(); 120 | mCalendar.setTimeInMillis(reminderTime);//设置开始时间 121 | long start = mCalendar.getTime().getTime(); 122 | mCalendar.setTimeInMillis(start + 10 * 60 * 1000);//设置终止时间,开始时间加10分钟 123 | long end = mCalendar.getTime().getTime(); 124 | ContentValues event = new ContentValues(); 125 | event.put("title", title); 126 | event.put("description", description); 127 | event.put("calendar_id", calId); //插入账户的id 128 | event.put(CalendarContract.Events.DTSTART, start); 129 | event.put(CalendarContract.Events.DTEND, end); 130 | event.put(CalendarContract.Events.HAS_ALARM, 1);//设置有闹钟提醒 131 | event.put(CalendarContract.Events.EVENT_TIMEZONE, "Asia/Shanghai");//这个是时区,必须有 132 | //设置每日提醒 133 | event.put(CalendarContract.Events.RRULE,"FREQ=DAILY"); 134 | Uri newEvent = context.getContentResolver().insert(Uri.parse(CALENDER_EVENT_URL), event); //添加事件 135 | if (newEvent == null) 136 | { //添加日历事件失败直接返回 137 | return; 138 | } 139 | 140 | //事件提醒的设定 141 | ContentValues values = new ContentValues(); 142 | values.put(CalendarContract.Reminders.EVENT_ID, ContentUris.parseId(newEvent)); 143 | values.put(CalendarContract.Reminders.MINUTES, previousDate * 24 * 60);// 提前previousDate天有提醒 144 | values.put(CalendarContract.Reminders.METHOD, CalendarContract.Reminders.METHOD_ALERT); 145 | Uri uri = context.getContentResolver().insert(Uri.parse(CALENDER_REMINDER_URL), values); 146 | if(uri == null) 147 | { //添加事件提醒失败直接返回 148 | return; 149 | } 150 | } 151 | 152 | /** 153 | * 删除日历事件 154 | */ 155 | public static void deleteCalendarEvent(Context context,String title) { 156 | if (context == null) { 157 | return; 158 | } 159 | Cursor eventCursor = context.getContentResolver().query(Uri.parse(CALENDER_EVENT_URL), null, null, null, null); 160 | try { 161 | if (eventCursor == null) { //查询返回空值 162 | return; 163 | } 164 | if (eventCursor.getCount() > 0) { 165 | //遍历所有事件,找到title跟需要查询的title一样的项 166 | for (eventCursor.moveToFirst(); !eventCursor.isAfterLast(); eventCursor.moveToNext()) { 167 | String eventTitle = eventCursor.getString(eventCursor.getColumnIndex("title")); 168 | if (!TextUtils.isEmpty(title) && title.equals(eventTitle)) { 169 | int id = eventCursor.getInt(eventCursor.getColumnIndex(CalendarContract.Calendars._ID));//取得id 170 | Uri deleteUri = ContentUris.withAppendedId(Uri.parse(CALENDER_EVENT_URL), id); 171 | int rows = context.getContentResolver().delete(deleteUri, null, null); 172 | if (rows == -1) { //事件删除失败 173 | return; 174 | } 175 | } 176 | } 177 | } 178 | } finally { 179 | if (eventCursor != null) { 180 | eventCursor.close(); 181 | } 182 | } 183 | } 184 | } 185 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/habittest/DBManager.java: -------------------------------------------------------------------------------- 1 | package com.example.habittest; 2 | 3 | import android.content.Context; 4 | import android.database.Cursor; 5 | import android.database.sqlite.SQLiteDatabase; 6 | 7 | import java.util.Date; 8 | 9 | public class DBManager { 10 | private static MySqliteHelper helper; 11 | private SQLiteDatabase db; 12 | 13 | public static MySqliteHelper getIntance(Context context) { 14 | if (helper == null) { 15 | helper = new MySqliteHelper(context); 16 | } 17 | return helper; 18 | } 19 | 20 | public DBManager(SQLiteDatabase db) { 21 | this.db = db; 22 | } 23 | 24 | 25 | //数据库创建函数 26 | public void createTableOrNot() { 27 | boolean notable = true; 28 | int count = -1; 29 | //先判断表是否存在 30 | String sql = "select count(*) as c from sqlite_master where type ='table' and name ='habits' "; 31 | Cursor cursor = db.rawQuery(sql, null); 32 | if (cursor.moveToNext()) { 33 | count = cursor.getInt(0); 34 | if (count > 0) { 35 | notable = false; 36 | } 37 | } 38 | if (notable) {//不存在则创建 39 | String sql1 = "create table habits (hname text primary key,pic text, total_num integer,finished_num integer,time text, fre text, htext text,days integer, curdays integer, highdays integer, credate text , swit integer)"; 40 | String sql2 = "create table daka (hname text,dakadate date)"; 41 | db.execSQL(sql1); 42 | db.execSQL(sql2); 43 | this.insertTestRecord(); 44 | } 45 | //调试用Log.i("tag",Integer.toString(count)); 46 | //调试用Log.i("tag",Boolean.toString(notable)); 47 | } 48 | 49 | public void insertTestRecord() { 50 | String sql1 = "insert into habits values ('测试习惯1','habit_1',2,0,'晨间习惯','每天','只有千锤百炼,才能成为好钢。',5,0,3,'20190526',1)"; 51 | String sql2 = "insert into habits values ('测试习惯2','habit_2',3,0,'午间习惯','每天','只有千锤百炼,才能成为好钢。',3,0,2,'20190515',1)"; 52 | String sql3 = "insert into habits values ('测试习惯3','habit_3',1,0,'晚间习惯','每天','只有千锤百炼,才能成为好钢。',4,0,2,'20190522',1)"; 53 | String sql4 = "insert into habits values ('测试习惯4','habit_4',1,0,'任意时间','每天','只有千锤百炼,才能成为好钢。',6,0,3,'20190531',1)"; 54 | 55 | String sql5 = "insert into daka values ('测试习惯1','20190601'),('测试习惯1','20190602'),('测试习惯1','20190603'),('测试习惯1','20190610'),('测试习惯1','20190611')"; 56 | String sql6 = "insert into daka values ('测试习惯2','20190603'),('测试习惯2','20190610'),('测试习惯2','20190611')"; 57 | String sql7 = "insert into daka values ('测试习惯3','20190603'),('测试习惯3','20190604'),('测试习惯3','20190610'),('测试习惯3','20190611')"; 58 | String sql8 = "insert into daka values ('测试习惯4','20190601'),('测试习惯4','20190602'),('测试习惯4','20190603'),('测试习惯4','20190609'),('测试习惯4','20190610'),('测试习惯4','20190611')"; 59 | 60 | db.execSQL(sql1); 61 | db.execSQL(sql2); 62 | db.execSQL(sql3); 63 | db.execSQL(sql4); 64 | db.execSQL(sql5); 65 | db.execSQL(sql6); 66 | db.execSQL(sql7); 67 | db.execSQL(sql8); 68 | } 69 | 70 | public void clockinUpdateDB(String h) { 71 | //点击签到键更新数据库 72 | 73 | //非必做操作 筛选更新 74 | String sql3 = "update habits set days = days+1 where hname='" + h + "' and finished_num=0"; 75 | String sql4 = "update habits set curdays = curdays+1 where hname='" + h + "' and finished_num=0 and curdays=0"; 76 | String sql5 = "update habits set highdays = highdays+1 where hname='" + h + "' and finished_num=0 and highdays=0"; 77 | db.execSQL(sql3); 78 | db.execSQL(sql4); 79 | db.execSQL(sql5); 80 | //必做操作:finished_num++ 、插入打卡记录 81 | Date date = new Date(); ///获取当前日期 82 | String date_s = Utils.date2String(date); 83 | String sql1 = "update habits set finished_num = finished_num+1 where hname ='" + h + "'"; 84 | String sql2 = "insert into daka values ('" + h + "','" + date_s + "')"; 85 | db.execSQL(sql1); 86 | db.execSQL(sql2); 87 | } 88 | 89 | //返回给定时间段下的习惯 90 | //isNotFinished为1时返回未结束的,为0返回已结束的 91 | public Habit[] getHabit(String time, int isNotFinished) { 92 | String[] Time = new String[]{time}; 93 | if (time == "任意时间") {//选中的是任意时间habits,返回全部habits 94 | String sql = "select count(*) from habits where swit=" + isNotFinished; 95 | Cursor cursor = db.rawQuery(sql, null); 96 | cursor.moveToNext(); 97 | int count = cursor.getInt(0);//获取习惯总数 98 | Habit[] h = new Habit[count];//创建habit数组 99 | String sq2 = "select * from habits where swit=" + isNotFinished; 100 | Cursor c = db.rawQuery(sq2, null); 101 | c.moveToFirst(); 102 | int i = 0; 103 | while (!c.isAfterLast()) { 104 | Habit h1 = new Habit(c.getString(0), c.getString(1), c.getInt(2), c.getInt(3), c.getString(4), c.getString(5), c.getString(6), c.getInt(7), c.getInt(8), c.getInt(9), c.getString(10), c.getInt(11)); 105 | h[i++] = h1; 106 | c.moveToNext(); 107 | } 108 | ///应当有count == h.length; 109 | return h; 110 | } else {//其它情况相似 111 | String sql1 = "select count(*) from habits where time=? and swit =" + isNotFinished; 112 | Cursor cursor = db.rawQuery(sql1, Time); 113 | cursor.moveToNext(); 114 | int count = cursor.getInt(0);//获取习惯总数 115 | Habit[] h = new Habit[count];//创建habit数组 116 | String sql2 = "select * from habits where time=? and swit =" + isNotFinished; 117 | Cursor c = db.rawQuery(sql2, Time); 118 | c.moveToFirst(); 119 | int i = 0; 120 | while (!c.isAfterLast()) { 121 | Habit h1 = new Habit(c.getString(0), c.getString(1), c.getInt(2), c.getInt(3), c.getString(4), c.getString(5), c.getString(6), c.getInt(7), c.getInt(8), c.getInt(9), c.getString(10), c.getInt(11)); 122 | h[i++] = h1; 123 | c.moveToNext(); 124 | } 125 | ///应当有count == h.length ==i;实际h数组的下标应该为0至i-1 126 | //调试用Log.i("tag##",Integer.toString(i)); 127 | return h; 128 | } 129 | } 130 | 131 | //用于在添加新的习惯时更新数据库,成功返回ture,失败返回false(表示该习惯已经存在)。 132 | public boolean insertHabitDB(Habit habit) { 133 | 134 | //第一步先看要添加的habit名称是否已经存在 135 | 136 | String sql1 = "select count(*) from habits where hname = '" + habit.getHname() + "'"; //sql语句查询是否存在该名字 137 | Cursor cursor = db.rawQuery(sql1, null); 138 | cursor.moveToFirst(); 139 | int count = cursor.getInt(0); 140 | if (count == 1) //若已经存在这个名字的习惯则直接返回false 141 | return false; 142 | //否则创建这个习惯。 143 | String sql2 = "insert into habits values('" + habit.getHname() + "','" + habit.getPic() + "'," + habit.getTotal_num() + "," + habit.getFinished_num() + ",'" + habit.getTime() + "','" + habit.getFre() + "','" + habit.getHtext() + "'," + habit.getDays() + "," + habit.getCurdays() + "," + habit.getHighdays() + ",'" + habit.getCredate() + "'," + habit.getSwit() + ")"; 144 | db.execSQL(sql2); 145 | return true; ///添加则返回true 146 | } 147 | 148 | public void switchHabit(String hname,int swit) { 149 | String sql = "update habits set swit = "+swit+" where hname='" + hname + "'"; 150 | db.execSQL(sql); 151 | } 152 | 153 | //获取查看的习惯已经打卡的日期,返回存放已打卡日期的int数组 154 | public int[] getDates(String hname) { 155 | int[] dates;//存放结果的int数组 156 | int count;//数组长度 通过查询记录获得 157 | String sql1 = "select count(*) from daka where hname = '" + hname + "'"; 158 | Cursor cursor = db.rawQuery(sql1, null); 159 | cursor.moveToFirst(); 160 | count = cursor.getInt(0); 161 | dates = new int[count]; ///获取该习惯打卡总数后,实例化int数组,准备存数据 162 | 163 | String sql2 = "select dakadate from daka where hname = '" + hname + "'"; 164 | Cursor c = db.rawQuery(sql2, null); 165 | c.moveToFirst(); 166 | int i = 0; 167 | while (!c.isAfterLast()) {//获取日期 168 | String s1 = c.getString(0); 169 | dates[i++] = Integer.parseInt(s1.substring(6, 8)); 170 | c.moveToNext(); 171 | } 172 | //while过后,应当有count==i==h.length,且s[]下标范围0至i-1 173 | 174 | return dates; 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/habittest/Fragment1.java: -------------------------------------------------------------------------------- 1 | package com.example.habittest; 2 | 3 | import android.database.Cursor; 4 | import android.database.sqlite.SQLiteDatabase; 5 | import android.os.Bundle; 6 | import android.support.v4.app.Fragment; 7 | import android.util.Log; 8 | import android.view.LayoutInflater; 9 | import android.view.View; 10 | import android.view.ViewGroup; 11 | import android.widget.AdapterView; 12 | import android.widget.Button; 13 | import android.widget.GridView; 14 | import android.widget.TextView; 15 | import android.widget.SimpleAdapter; 16 | import android.widget.Toast; 17 | import android.widget.Toolbar; 18 | 19 | import java.util.ArrayList; 20 | import java.util.Date; 21 | import java.util.HashMap; 22 | import java.util.List; 23 | import java.util.Map; 24 | 25 | public class Fragment1 extends Fragment { 26 | Habit[] habit; 27 | private View v; 28 | private GridView gview; 29 | private List> data_list; 30 | private SimpleAdapter sim_adapter; 31 | 32 | //选择时间button 33 | private Button[] bt = new Button[4]; 34 | //当前选择的时间段 35 | private String[] t = {"任意时间", "晨间习惯", "午间习惯", "晚间习惯"}; 36 | private String time; 37 | 38 | //数据库manager 39 | private DBManager mgr; 40 | 41 | public void setDBManager(DBManager mgr) { 42 | this.mgr = mgr; 43 | } 44 | 45 | @Override 46 | public void onResume() { 47 | super.onResume(); 48 | selectTime(0); 49 | } 50 | 51 | @Override 52 | public View onCreateView(LayoutInflater inflater, ViewGroup container, 53 | Bundle savedInstanceState) { 54 | v = inflater.inflate(R.layout.habit_grid, container, false); 55 | 56 | //选择时间button 57 | bt[0] = (Button) v.findViewById(R.id.anytime); 58 | bt[1] = (Button) v.findViewById(R.id.morning); 59 | bt[2] = (Button) v.findViewById(R.id.noon); 60 | bt[3] = (Button) v.findViewById(R.id.evening); 61 | 62 | //设置默认选择任意时间 63 | selectTime(0); 64 | //选择时间事件 65 | for (int i = 0; i < 4; i++) { 66 | bt[i].setOnClickListener(new View.OnClickListener() { 67 | @Override 68 | public void onClick(View v) { 69 | switch (v.getId()) { 70 | case R.id.anytime: 71 | selectTime(0); 72 | break; 73 | case R.id.morning: 74 | selectTime(1); 75 | break; 76 | case R.id.noon: 77 | selectTime(2); 78 | break; 79 | case R.id.evening: 80 | selectTime(3); 81 | break; 82 | } 83 | } 84 | }); 85 | } 86 | 87 | 88 | //监听点击事件 89 | gview.setOnItemClickListener(new AdapterView.OnItemClickListener() { 90 | @Override 91 | public void onItemClick(AdapterView adapterView, View view, int i, long j) { 92 | change_data(i); 93 | } 94 | }); 95 | 96 | 97 | return v; 98 | } 99 | 100 | public void getData() { 101 | //cion和iconName的长度是相同的,这里任选其一都可以 102 | for (int i = 0; i < habit.length; i++) { 103 | Map map = new HashMap(); 104 | map.put("imageView2", getResources().getIdentifier(habit[i].pic, "drawable", getContext().getApplicationInfo().packageName)); 105 | map.put("text_habit_name", habit[i].hname); 106 | map.put("text_signed_info", habit[i].finished_num + "/" + habit[i].total_num); 107 | data_list.add(map); 108 | } 109 | } 110 | 111 | //选择时间事件 112 | public void selectTime(int k) { 113 | for (int i = 0; i < 4; i++) { 114 | if (k == i) { 115 | bt[i].setBackgroundResource(R.drawable.shape_1_selected); 116 | } else { 117 | bt[i].setBackgroundResource(R.drawable.shape_1); 118 | } 119 | } 120 | time = t[k]; 121 | habit = mgr.getHabit(time, 1); 122 | for (int i = 0; i < habit.length; i++) { 123 | if (habit[i].finished_num == habit[i].total_num) { 124 | habit[i].pic = habit[i].pic + "_gray"; 125 | } 126 | } 127 | refresh_grid(); 128 | } 129 | 130 | //更新视图 131 | private void refresh_grid() { 132 | gview = (GridView) v.findViewById(R.id._dynamic); 133 | //新建List 134 | data_list = new ArrayList>(); 135 | //获取数据 136 | getData(); 137 | //新建适配器 138 | String[] from = {"imageView2", "text_habit_name", "text_signed_info"};//传入数据 139 | int[] to = {R.id.imageView2, R.id.text_habit_name, R.id.text_signed_info};//传出数据 140 | sim_adapter = new SimpleAdapter(getActivity(), data_list, R.layout.grid_item, from, to); 141 | //配置适配器 142 | gview.setAdapter(sim_adapter); 143 | } 144 | 145 | 146 | //点击的时候更新数据 147 | private void change_data(int item_id) { 148 | if (habit[item_id].finished_num < habit[item_id].total_num) { 149 | habit[item_id].finished_num++; 150 | if (habit[item_id].finished_num == habit[item_id].total_num) 151 | habit[item_id].pic = habit[item_id].pic + "_gray"; 152 | refresh_grid(); 153 | Toast.makeText(getActivity(), habit[item_id].hname + "已打卡成功", Toast.LENGTH_SHORT).show(); 154 | 155 | //更新数据库 156 | mgr.clockinUpdateDB(habit[item_id].hname); 157 | } else { 158 | Toast.makeText(getActivity(), habit[item_id].hname + "已完成", Toast.LENGTH_SHORT).show(); 159 | } 160 | } 161 | 162 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/habittest/Fragment2.java: -------------------------------------------------------------------------------- 1 | package com.example.habittest; 2 | 3 | import android.content.Intent; 4 | import android.graphics.Bitmap; 5 | import android.graphics.BitmapFactory; 6 | import android.os.Bundle; 7 | import android.support.v4.app.Fragment; 8 | import android.view.LayoutInflater; 9 | import android.view.View; 10 | import android.view.ViewDebug; 11 | import android.view.ViewGroup; 12 | import android.widget.AdapterView; 13 | import android.widget.ListView; 14 | import android.widget.Toast; 15 | 16 | import java.util.ArrayList; 17 | import java.util.HashMap; 18 | import java.util.List; 19 | import java.util.Objects; 20 | 21 | 22 | public class Fragment2 extends Fragment { 23 | 24 | private List list; 25 | private ListView listView; 26 | private HabitListItemAdapter itemAdapter; 27 | 28 | private Habit[]habit; 29 | 30 | //数据库manager 31 | private DBManager mgr; 32 | 33 | public void setDBManager(DBManager mgr) { 34 | this.mgr = mgr; 35 | } 36 | 37 | @Override 38 | public void onResume() { 39 | super.onResume(); 40 | refresh_list(); 41 | } 42 | 43 | @Override 44 | public View onCreateView(final LayoutInflater inflater, ViewGroup container, 45 | Bundle savedInstanceState) { 46 | View view = inflater.inflate(R.layout.all_habits, container, false); 47 | listView = (ListView) view.findViewById(R.id.ListView0); 48 | 49 | listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { 50 | @Override 51 | public void onItemClick(AdapterView adapterView, View view, int i, long j) { 52 | Intent intent = new Intent(getActivity(), HabitLog.class); 53 | intent.putExtra("isFinished",0); 54 | intent.putExtra("name",habit[i].hname); 55 | intent.putExtra("days",habit[i].days+""); 56 | intent.putExtra("curdays",habit[i].curdays+""); 57 | intent.putExtra("highdays",habit[i].highdays+""); 58 | intent.putExtra("credate",habit[i].credate); 59 | startActivity(intent); 60 | } 61 | }); 62 | 63 | refresh_list(); 64 | return view; 65 | } 66 | 67 | public void refresh_list() { 68 | list = new ArrayList(); 69 | habit = mgr.getHabit("任意时间", 1); 70 | for (int i = 0; i < habit.length; i++) { 71 | HabitListItem t = new HabitListItem(habit[i].hname, habit[i].htext, habit[i].days + "", habit[i].pic); 72 | list.add(t); 73 | } 74 | itemAdapter = new HabitListItemAdapter(getActivity(), R.layout.habit_list_item, list); 75 | listView.setAdapter(itemAdapter); 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/habittest/Fragment3.java: -------------------------------------------------------------------------------- 1 | package com.example.habittest; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import android.support.constraint.ConstraintLayout; 6 | import android.support.v4.app.Fragment; 7 | import android.view.LayoutInflater; 8 | import android.view.View; 9 | import android.view.ViewGroup; 10 | 11 | 12 | public class Fragment3 extends Fragment { 13 | 14 | private byte[] image; 15 | 16 | @Override 17 | public View onCreateView(final LayoutInflater inflater, ViewGroup container, 18 | Bundle savedInstanceState) { 19 | View v = inflater.inflate(R.layout.mine, container, false); 20 | 21 | ConstraintLayout c = (ConstraintLayout) v.findViewById(R.id.constraintLayout7); 22 | c.setOnClickListener(new View.OnClickListener() { 23 | @Override 24 | public void onClick(View v) { 25 | Intent intent = new Intent(getActivity(), TodayCard.class); 26 | intent.putExtra("image", image); 27 | startActivity(intent); 28 | } 29 | }); 30 | 31 | ConstraintLayout c2 = (ConstraintLayout) v.findViewById(R.id.constraintLayout9); 32 | c2.setOnClickListener(new View.OnClickListener() { 33 | @Override 34 | public void onClick(View v) { 35 | Intent intent = new Intent(getActivity(), AboutUs.class); 36 | startActivity(intent); 37 | } 38 | }); 39 | 40 | ConstraintLayout c3 = (ConstraintLayout) v.findViewById(R.id.constraintLayout6); 41 | c3.setOnClickListener(new View.OnClickListener() { 42 | @Override 43 | public void onClick(View v) { 44 | Intent intent = new Intent(getActivity(), OverHabit.class); 45 | startActivity(intent); 46 | } 47 | }); 48 | 49 | ConstraintLayout c4 = (ConstraintLayout) v.findViewById(R.id.constraintLayout8); 50 | c4.setOnClickListener(new View.OnClickListener() { 51 | @Override 52 | public void onClick(View v) { 53 | Intent intent = new Intent(getActivity(), HelpLayout.class); 54 | startActivity(intent); 55 | } 56 | }); 57 | 58 | return v; 59 | } 60 | 61 | public void setImage(byte[] image) { 62 | this.image = image; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/habittest/Habit.java: -------------------------------------------------------------------------------- 1 | package com.example.habittest; 2 | 3 | public class Habit { 4 | public String hname; //习惯名 5 | public String pic; //习惯图标 6 | public int total_num; //习惯每日需完成次数 7 | public String time; //习惯时间区间:晨间习惯、午间、晚间、任意时间 8 | public String fre; //习惯频率:每日、每周、每月 9 | public String htext; //习惯标注 10 | public int finished_num; //习惯今日已完成次数 11 | public int days; //坚持天数 12 | public int curdays; //当前已坚持天数 13 | public int highdays; //最高坚持天数 14 | public String credate; //创建日期 15 | public int swit; //习惯是否开启 16 | 17 | 18 | public Habit(String h, String p, int t, int f, String time, String fre, String htext, int d, int c, int high, String cre, int swit) { 19 | setHname(h); 20 | setPic(p); 21 | setTotal_num(t); 22 | setFinished_num(f); 23 | 24 | setTime(time); 25 | setFre(fre); 26 | setHtext(htext); 27 | setDays(d); 28 | 29 | setCurdays(c); 30 | setHighdays(high); 31 | setCredate(cre); 32 | setSwit(swit); 33 | } 34 | 35 | public int getSwit() { 36 | return swit; 37 | } 38 | 39 | public void setSwit(int swit) { 40 | this.swit = swit; 41 | } 42 | 43 | public int getCurdays() { 44 | return curdays; 45 | } 46 | 47 | public void setCurdays(int curdays) { 48 | this.curdays = curdays; 49 | } 50 | 51 | public int getHighdays() { 52 | return highdays; 53 | } 54 | 55 | public void setHighdays(int highdays) { 56 | this.highdays = highdays; 57 | } 58 | 59 | public String getCredate() { 60 | return credate; 61 | } 62 | 63 | public void setCredate(String credate) { 64 | this.credate = credate; 65 | } 66 | 67 | 68 | public String getHname() { 69 | return hname; 70 | } 71 | 72 | public void setHname(String hname) { 73 | this.hname = hname; 74 | } 75 | 76 | public String getPic() { 77 | return pic; 78 | } 79 | 80 | public void setPic(String pic) { 81 | this.pic = pic; 82 | } 83 | 84 | public int getTotal_num() { 85 | return total_num; 86 | } 87 | 88 | public void setTotal_num(int total_num) { 89 | this.total_num = total_num; 90 | } 91 | 92 | public String getTime() { 93 | return time; 94 | } 95 | 96 | public void setTime(String time) { 97 | this.time = time; 98 | } 99 | 100 | public String getFre() { 101 | return fre; 102 | } 103 | 104 | public void setFre(String fre) { 105 | this.fre = fre; 106 | } 107 | 108 | public String getHtext() { 109 | return htext; 110 | } 111 | 112 | public void setHtext(String htext) { 113 | this.htext = htext; 114 | } 115 | 116 | public int getFinished_num() { 117 | return finished_num; 118 | } 119 | 120 | public void setFinished_num(int finished_num) { 121 | this.finished_num = finished_num; 122 | } 123 | 124 | public int getDays() { 125 | return days; 126 | } 127 | 128 | public void setDays(int days) { 129 | this.days = days; 130 | } 131 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/habittest/HabitListItem.java: -------------------------------------------------------------------------------- 1 | package com.example.habittest; 2 | 3 | public class HabitListItem { 4 | 5 | private String name; 6 | private String time; 7 | private String days; 8 | private String picPath; 9 | 10 | public String getName() { 11 | return name; 12 | } 13 | 14 | public String getTime() { 15 | return time; 16 | } 17 | 18 | public String getDays() { 19 | return days; 20 | } 21 | 22 | public String getPicPath() { 23 | return picPath; 24 | } 25 | 26 | public void setName(String name) { 27 | this.name = name; 28 | } 29 | 30 | public void setTime(String time) { 31 | this.time = time; 32 | } 33 | 34 | public void setDays(String days) { 35 | this.days = days; 36 | } 37 | 38 | public void setPicPath(String picPath) { 39 | this.picPath = picPath; 40 | } 41 | 42 | 43 | public HabitListItem(String name, String time, String days, String picPath) { 44 | this.name = name; 45 | this.time = time; 46 | this.days = days; 47 | this.picPath = picPath; 48 | } 49 | 50 | 51 | } 52 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/habittest/HabitListItemAdapter.java: -------------------------------------------------------------------------------- 1 | package com.example.habittest; 2 | 3 | import android.content.Context; 4 | import android.graphics.BitmapFactory; 5 | import android.support.annotation.NonNull; 6 | import android.view.LayoutInflater; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | import android.widget.ArrayAdapter; 10 | import android.widget.ImageView; 11 | import android.widget.TextView; 12 | 13 | import java.util.List; 14 | 15 | public class HabitListItemAdapter extends ArrayAdapter { 16 | private int layoutId; 17 | 18 | public HabitListItemAdapter(Context context, int layoutId, List list) { 19 | super(context, layoutId, list); 20 | this.layoutId = layoutId; 21 | } 22 | 23 | @NonNull 24 | @Override 25 | public View getView(int position, View convertView, ViewGroup parent) { 26 | HabitListItem item = getItem(position); 27 | View view = LayoutInflater.from(getContext()).inflate(layoutId, parent, false); 28 | 29 | ImageView imageView = (ImageView) view.findViewById(R.id.imageView); 30 | TextView textName = (TextView) view.findViewById(R.id.text_name); 31 | TextView textTime = (TextView) view.findViewById(R.id.text_time); 32 | TextView textDays = (TextView) view.findViewById(R.id.text_days); 33 | imageView.setImageResource(getContext().getResources().getIdentifier(item.getPicPath(),"drawable",getContext().getApplicationInfo().packageName)); 34 | textName.setText(item.getName()); 35 | textTime.setText(item.getTime()); 36 | textDays.setText(item.getDays()); 37 | return view; 38 | } 39 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/habittest/HabitLog.java: -------------------------------------------------------------------------------- 1 | package com.example.habittest; 2 | 3 | 4 | import android.content.Intent; 5 | import android.database.sqlite.SQLiteDatabase; 6 | import android.support.v7.app.AppCompatActivity; 7 | import android.os.Bundle; 8 | import android.support.v7.widget.Toolbar; 9 | import android.view.View; 10 | import android.widget.Button; 11 | import android.widget.GridView; 12 | import android.widget.ImageView; 13 | import android.widget.SimpleAdapter; 14 | import android.widget.TextView; 15 | 16 | import java.util.ArrayList; 17 | import java.util.Calendar; 18 | import java.util.HashMap; 19 | import java.util.List; 20 | import java.util.Map; 21 | 22 | public class HabitLog extends AppCompatActivity { 23 | 24 | GridView grv; 25 | private List> data_list; 26 | private SimpleAdapter sim_adapter; 27 | private String[] WeekDays = {"日", "一", "二", "三", "四", "五", "六"}; 28 | private int[] sign_days; 29 | 30 | private String hname;//习惯名 31 | 32 | //数据库相关变量 33 | private MySqliteHelper helper; 34 | private SQLiteDatabase db; 35 | private DBManager mgr; 36 | 37 | private int isFinished;//习惯是否完成 1:结束 0:未结束 38 | 39 | //分享相关 40 | private String days1;//总打卡 41 | private String days2;//当前连续打卡 42 | 43 | @Override 44 | protected void onCreate(Bundle savedInstanceState) { 45 | super.onCreate(savedInstanceState); 46 | setContentView(R.layout.activity_habit_log); 47 | 48 | //数据库变量初始化 49 | helper = DBManager.getIntance(this); 50 | db = helper.getWritableDatabase();//创建或打开数据库 51 | mgr = new DBManager(db); 52 | 53 | Intent intent = getIntent(); 54 | isFinished = intent.getIntExtra("isFinished", 0); 55 | 56 | hname = intent.getStringExtra("name"); 57 | String days = intent.getStringExtra("days"); 58 | String curdays = intent.getStringExtra("curdays"); 59 | String highdays = intent.getStringExtra("highdays"); 60 | String credate = intent.getStringExtra("credate"); 61 | String date = credate.substring(0, 4) + "." + credate.substring(4, 6) + "." + credate.substring(6, 8); 62 | 63 | TextView topName = (TextView) findViewById(R.id.top_habit_name); 64 | TextView tdays = (TextView) findViewById(R.id.textView11); 65 | TextView tcurdays = (TextView) findViewById(R.id.textView13); 66 | TextView thighdays = (TextView) findViewById(R.id.textView15); 67 | TextView tcredate = (TextView) findViewById(R.id.textView17); 68 | topName.setText(hname); 69 | tdays.setText(days + "天"); 70 | tcurdays.setText(curdays + "天"); 71 | thighdays.setText(highdays + "天"); 72 | tcredate.setText(date); 73 | //分享相关变量 74 | days1 = days + "天"; 75 | days2 = curdays + "天"; 76 | 77 | if (isFinished == 1) { 78 | //已结束的习惯不可分享 79 | ImageView share = (ImageView) findViewById(R.id.imageView6); 80 | share.setVisibility(View.GONE); 81 | Button bt = (Button) findViewById(R.id.button2); 82 | bt.setText("激活习惯"); 83 | } 84 | 85 | sign_days = mgr.getDates(hname); 86 | 87 | Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar3); 88 | toolbar.setNavigationOnClickListener(new View.OnClickListener() { 89 | @Override 90 | public void onClick(View view) { 91 | finish(); 92 | } 93 | }); 94 | setdate(); 95 | } 96 | 97 | public void setdate() { 98 | //获取当前日期 99 | //获取当前是周几 100 | //获取当前月份天数 101 | //获取已经打卡的列表 102 | int[] mongth_day = new int[]{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 103 | grv = (GridView) findViewById(R.id.grid_date); 104 | Calendar calendar = Calendar.getInstance(); 105 | Calendar calendar1 = Calendar.getInstance(); 106 | calendar1.set(Calendar.DAY_OF_MONTH, 1);//设为当前月份第一天 107 | int y = calendar.get(Calendar.YEAR);//年 108 | int month = calendar.get(Calendar.MONTH);//获取当前月份(作为下标) 109 | mongth_day[1] = (y % 4 == 0 && y % 100 != 0 || y % 400 == 0) ? 29 : 28; 110 | int day_mon = mongth_day[month];//当月天数 111 | int week_days = calendar1.get(Calendar.DAY_OF_WEEK);//1-7:周日——周一 112 | int now_day = calendar.get(Calendar.DAY_OF_MONTH);//当前是第几天 113 | int i, j;//计数 114 | int emp_num = week_days - 1;//周1——6空1——6,日不空格 115 | j = 7 + emp_num + day_mon; 116 | //新建List 117 | data_list = new ArrayList>(); 118 | //获取数据 119 | for (i = 0; i < j; i++) { 120 | Map map = new HashMap(); 121 | if (i < 7)//展示周日——周一 122 | { 123 | map.put("textView_date", "\n" + WeekDays[i]); 124 | map.put("image_back_date", R.drawable.pure); 125 | map.put("image_sign_point", R.drawable.pure); 126 | } else if (i < 7 + emp_num) { 127 | map.put("textView_date", " "); 128 | map.put("image_back_date", R.drawable.pure); 129 | map.put("image_sign_point", R.drawable.pure); 130 | } else { 131 | int tempday = i - 6 - emp_num; 132 | map.put("textView_date", "\n" + tempday); 133 | if (tempday == now_day) { 134 | map.put("image_back_date", R.drawable.shadow_date); 135 | } else { 136 | map.put("image_back_date", R.drawable.pure); 137 | } 138 | //需要判断已经做得 139 | if (judge_int_exist(sign_days, tempday)) { 140 | map.put("image_sign_point", R.drawable.sign_point); 141 | } else { 142 | map.put("image_sign_point", R.drawable.pure); 143 | } 144 | } 145 | 146 | data_list.add(map); 147 | } 148 | //新建适配器 149 | String[] from = {"textView_date", "image_back_date", "image_sign_point"};//传入数据 150 | int[] to = {R.id.textView_date, R.id.image_back_date, R.id.image_sign_point};//传出数据 151 | sim_adapter = new SimpleAdapter(this, data_list, R.layout.date_item, from, to); 152 | //配置适配器 153 | grv.setAdapter(sim_adapter); 154 | 155 | 156 | // Inflate the layout for this fragment 157 | } 158 | 159 | //判断数组中是否有某个值 160 | public boolean judge_int_exist(int[] s, int num) { 161 | boolean exist = false; 162 | int l = s.length; 163 | for (int i = 0; i < l; i++) { 164 | if (s[i] == num) { 165 | exist = true; 166 | break; 167 | } 168 | } 169 | return exist; 170 | } 171 | 172 | public void finishHabit(View view) { 173 | if (isFinished == 0) { 174 | //结束习惯删除日程提醒 175 | CalendarReminderUtils.deleteCalendarEvent(this, hname); 176 | } 177 | mgr.switchHabit(hname, isFinished); 178 | finish(); 179 | } 180 | 181 | 182 | public void share(View view) { 183 | shareText("习惯分享", "我正在养成习惯:" + hname + ",目前已连续打卡" + days2 + ",总共打卡" + days1 + "。快来一起使用习惯养成App吧!"); 184 | } 185 | 186 | public void shareText(String title, String text) { 187 | Intent intent = new Intent(Intent.ACTION_SEND); 188 | intent.setType("text/plain"); 189 | intent.putExtra(Intent.EXTRA_SUBJECT, title); 190 | intent.putExtra(Intent.EXTRA_TEXT, text); 191 | intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 192 | startActivity(Intent.createChooser(intent, "分享文字")); 193 | } 194 | } 195 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/habittest/HelpLayout.java: -------------------------------------------------------------------------------- 1 | package com.example.habittest; 2 | 3 | import android.os.Bundle; 4 | import android.support.v7.app.AppCompatActivity; 5 | import android.view.View; 6 | 7 | public class HelpLayout extends AppCompatActivity { 8 | @Override 9 | protected void onCreate(Bundle savedInstanceState) { 10 | super.onCreate(savedInstanceState); 11 | setContentView(R.layout.help); 12 | 13 | android.support.v7.widget.Toolbar toolbar = (android.support.v7.widget.Toolbar) findViewById(R.id.toolbar7); 14 | toolbar.setNavigationOnClickListener(new View.OnClickListener() { 15 | @Override 16 | public void onClick(View view) { 17 | finish(); 18 | } 19 | }); 20 | 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/habittest/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.habittest; 2 | 3 | import android.Manifest; 4 | import android.app.Fragment; 5 | import android.content.Context; 6 | import android.content.Intent; 7 | import android.content.pm.PackageManager; 8 | import android.database.sqlite.SQLiteDatabase; 9 | import android.os.Bundle; 10 | import android.support.annotation.NonNull; 11 | import android.support.annotation.Nullable; 12 | import android.support.design.widget.BottomNavigationView; 13 | import android.support.v4.app.ActivityCompat; 14 | import android.support.v4.app.FragmentManager; 15 | import android.support.v4.app.FragmentTransaction; 16 | import android.support.v4.content.ContextCompat; 17 | import android.support.v7.app.AppCompatActivity; 18 | import android.support.v7.widget.Toolbar; 19 | import android.util.Log; 20 | import android.view.LayoutInflater; 21 | import android.view.MenuItem; 22 | import android.view.View; 23 | import android.view.ViewGroup; 24 | import android.view.Window; 25 | import android.widget.Button; 26 | import android.widget.FrameLayout; 27 | import android.widget.ListView; 28 | import android.widget.TextView; 29 | import android.widget.Toast; 30 | 31 | import org.jsoup.Jsoup; 32 | import org.jsoup.nodes.Document; 33 | import org.jsoup.nodes.Element; 34 | import org.jsoup.select.Elements; 35 | 36 | import java.io.ByteArrayOutputStream; 37 | import java.io.InputStream; 38 | import java.net.HttpURLConnection; 39 | import java.net.URL; 40 | import java.util.ArrayList; 41 | import java.util.List; 42 | 43 | public class MainActivity extends AppCompatActivity { 44 | List mPermissionList = new ArrayList<>();//权限集合 45 | String[] permissions = new String[]{Manifest.permission.READ_CALENDAR, Manifest.permission.WRITE_CALENDAR, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}; 46 | private TextView mTextMessage, top_text; 47 | private FragmentTransaction transaction; 48 | private FragmentManager fragmentManager; 49 | private Toolbar top_tools; 50 | private Button top_button; 51 | private FrameLayout frameLayout; 52 | //用于展示listview 53 | private List list = new ArrayList(); 54 | private ListView listView; 55 | private HabitListItemAdapter itemAdapter; 56 | 57 | //数据库相关变量 58 | private MySqliteHelper helper; 59 | private SQLiteDatabase db; 60 | private DBManager mgr; 61 | 62 | //今日图片 63 | private byte[] image; 64 | 65 | private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener 66 | = new BottomNavigationView.OnNavigationItemSelectedListener() { 67 | 68 | @Override 69 | public boolean onNavigationItemSelected(@NonNull MenuItem item) { 70 | fragmentManager = getSupportFragmentManager(); 71 | transaction = fragmentManager.beginTransaction(); 72 | switch (item.getItemId()) { 73 | case R.id.navigation_home: 74 | Fragment1 frag1 = new Fragment1(); 75 | frag1.setDBManager(mgr); 76 | transaction.replace(R.id.content, frag1); 77 | top_text.setText(R.string.top_today); 78 | top_button.setVisibility(View.VISIBLE); 79 | transaction.commit(); 80 | return true; 81 | case R.id.navigation_dashboard: 82 | Fragment2 frag2 = new Fragment2(); 83 | frag2.setDBManager(mgr); 84 | transaction.replace(R.id.content, frag2); 85 | top_text.setText(R.string.top_all); 86 | top_button.setVisibility(View.GONE); 87 | transaction.commit(); 88 | return true; 89 | case R.id.navigation_notifications: 90 | Fragment3 frag3 = new Fragment3(); 91 | frag3.setImage(image); 92 | transaction.replace(R.id.content, frag3); 93 | top_text.setText(R.string.top_mine); 94 | top_button.setVisibility(View.GONE); 95 | transaction.commit(); 96 | return true; 97 | } 98 | return false; 99 | } 100 | }; 101 | 102 | @Override 103 | protected void onCreate(Bundle savedInstanceState) { 104 | //关于申请权限的代码 105 | mPermissionList.clear(); 106 | for (int i = 0; i < permissions.length; i++) { 107 | if (ContextCompat.checkSelfPermission(MainActivity.this, permissions[i]) != PackageManager.PERMISSION_GRANTED) { 108 | mPermissionList.add(permissions[i]); 109 | } 110 | } 111 | if (mPermissionList.isEmpty()) {//未授予的权限为空,表示都授予了 112 | //Toast.makeText(MainActivity.this, "已经授权", Toast.LENGTH_LONG).show(); 113 | } else {//请求权限方法 114 | String[] permissions = mPermissionList.toArray(new String[mPermissionList.size()]);//将List转为数组 115 | ActivityCompat.requestPermissions(MainActivity.this, permissions, 2); 116 | } //申请结束 117 | 118 | //数据库变量初始化 119 | helper = DBManager.getIntance(this); 120 | db = helper.getWritableDatabase();//创建或打开数据库 121 | mgr = new DBManager(db); 122 | //创建表 123 | mgr.createTableOrNot(); 124 | 125 | 126 | // 今日卡片图片爬虫 127 | new Thread() { 128 | @Override 129 | public void run() { 130 | super.run(); 131 | 132 | try { 133 | Document document = Jsoup.connect("https://cn.bing.com/HPImageArchive.aspx?idx=0&n=1").get(); 134 | Elements elements = document.select("images image url"); 135 | String imageUrl = elements.get(0).text(); 136 | 137 | String path = "https://cn.bing.com/" + imageUrl; 138 | URL url = new URL(path); 139 | HttpURLConnection con = (HttpURLConnection) url.openConnection(); 140 | con.setRequestMethod("GET"); 141 | con.setConnectTimeout(1000); 142 | con.setReadTimeout(1000); 143 | InputStream inStream = con.getInputStream(); 144 | 145 | int len = 0; 146 | byte[] buffer = new byte[1024]; 147 | ByteArrayOutputStream outStream = new ByteArrayOutputStream(); 148 | while ((len = inStream.read(buffer)) != -1) { 149 | outStream.write(buffer, 0, len); 150 | } 151 | inStream.close(); 152 | image = outStream.toByteArray(); 153 | } catch (Exception e) { 154 | e.printStackTrace(); 155 | } 156 | } 157 | }.start(); 158 | 159 | super.onCreate(savedInstanceState); 160 | supportRequestWindowFeature(Window.FEATURE_NO_TITLE); 161 | setContentView(R.layout.activity_main); 162 | setDefaultFragment(); 163 | mTextMessage = (TextView) findViewById(R.id.message); 164 | BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation); 165 | navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener); 166 | top_tools = (Toolbar) findViewById(R.id.toolbar); 167 | top_text = (TextView) findViewById(R.id.top_text); 168 | top_button = (Button) findViewById(R.id.top_button); 169 | 170 | } 171 | 172 | // 设置默认进来是tab 显示的页面 173 | private void setDefaultFragment() { 174 | fragmentManager = getSupportFragmentManager(); 175 | transaction = fragmentManager.beginTransaction(); 176 | Fragment1 frag1 = new Fragment1(); 177 | frag1.setDBManager(mgr); 178 | transaction.replace(R.id.content, frag1); 179 | transaction.commit(); 180 | } 181 | 182 | public void addHabit(View v) { 183 | Intent intent = new Intent(MainActivity.this, AddHabit.class); 184 | startActivity(intent); 185 | } 186 | 187 | } 188 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/habittest/MySqliteHelper.java: -------------------------------------------------------------------------------- 1 | package com.example.habittest; 2 | 3 | import android.content.Context; 4 | import android.database.sqlite.SQLiteDatabase; 5 | import android.database.sqlite.SQLiteOpenHelper; 6 | import android.util.Log; 7 | 8 | public class MySqliteHelper extends SQLiteOpenHelper { 9 | 10 | public MySqliteHelper(Context context) { 11 | super(context, "habitNB.db", null, 1); 12 | } 13 | 14 | @Override 15 | public void onCreate(SQLiteDatabase db) { 16 | Log.i("tag", "+++++++++++onCreate++++++++++"); 17 | } 18 | 19 | @Override 20 | public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 21 | 22 | } 23 | 24 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/habittest/OverHabit.java: -------------------------------------------------------------------------------- 1 | package com.example.habittest; 2 | 3 | import android.content.Intent; 4 | import android.database.sqlite.SQLiteDatabase; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.os.Bundle; 7 | import android.view.View; 8 | import android.widget.AdapterView; 9 | import android.widget.ListView; 10 | 11 | import java.util.ArrayList; 12 | import java.util.List; 13 | 14 | public class OverHabit extends AppCompatActivity { 15 | 16 | private List list; 17 | private ListView listView; 18 | private HabitListItemAdapter itemAdapter; 19 | 20 | private Habit[] habit; 21 | 22 | //数据库相关变量 23 | private MySqliteHelper helper; 24 | private SQLiteDatabase db; 25 | private DBManager mgr; 26 | 27 | @Override 28 | public void onResume() { 29 | super.onResume(); 30 | refresh_list(); 31 | } 32 | 33 | @Override 34 | protected void onCreate(Bundle savedInstanceState) { 35 | super.onCreate(savedInstanceState); 36 | setContentView(R.layout.activity_over_habit); 37 | 38 | //数据库变量初始化 39 | helper = DBManager.getIntance(this); 40 | db = helper.getWritableDatabase();//创建或打开数据库 41 | mgr = new DBManager(db); 42 | 43 | listView = (ListView) findViewById(R.id.dynamic); 44 | android.support.v7.widget.Toolbar toolbar = (android.support.v7.widget.Toolbar) findViewById(R.id.toolbar6); 45 | toolbar.setNavigationOnClickListener(new View.OnClickListener() { 46 | @Override 47 | public void onClick(View view) { 48 | finish(); 49 | } 50 | }); 51 | 52 | listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { 53 | @Override 54 | public void onItemClick(AdapterView adapterView, View view, int i, long j) { 55 | Intent intent = new Intent(OverHabit.this, HabitLog.class); 56 | intent.putExtra("isFinished", 1); 57 | intent.putExtra("name", habit[i].hname); 58 | intent.putExtra("days", habit[i].days + ""); 59 | intent.putExtra("curdays", habit[i].curdays + ""); 60 | intent.putExtra("highdays", habit[i].highdays + ""); 61 | intent.putExtra("credate", habit[i].credate); 62 | startActivity(intent); 63 | } 64 | }); 65 | refresh_list(); 66 | } 67 | 68 | public void refresh_list() { 69 | list = new ArrayList(); 70 | habit = mgr.getHabit("任意时间", 0); 71 | for (int i = 0; i < habit.length; i++) { 72 | HabitListItem t = new HabitListItem(habit[i].hname, habit[i].htext, habit[i].days + "", habit[i].pic); 73 | list.add(t); 74 | } 75 | itemAdapter = new HabitListItemAdapter(this, R.layout.habit_list_item, list); 76 | listView.setAdapter(itemAdapter); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/habittest/TodayCard.java: -------------------------------------------------------------------------------- 1 | package com.example.habittest; 2 | 3 | import android.content.Intent; 4 | import android.graphics.Bitmap; 5 | import android.graphics.BitmapFactory; 6 | import android.graphics.Canvas; 7 | import android.net.Uri; 8 | import android.os.Environment; 9 | import android.support.v4.content.FileProvider; 10 | import android.support.v7.app.AppCompatActivity; 11 | import android.os.Bundle; 12 | import android.view.View; 13 | import android.widget.ImageView; 14 | import android.widget.TextView; 15 | 16 | import java.io.ByteArrayOutputStream; 17 | import java.io.File; 18 | import java.io.FileNotFoundException; 19 | import java.io.FileOutputStream; 20 | import java.io.IOException; 21 | import java.io.InputStream; 22 | import java.net.HttpURLConnection; 23 | import java.net.URL; 24 | import java.time.LocalDate; 25 | import java.util.Calendar; 26 | import java.util.Date; 27 | 28 | import javax.net.ssl.HttpsURLConnection; 29 | 30 | public class TodayCard extends AppCompatActivity { 31 | 32 | private String[] img = {"card_1", "card_2", "card_3", "card_4", "card_5", "card_6"}; 33 | private String[] words = {"Great works are performed not by strength, but by perseverance.\n完成伟大的事业不在于体力,而在于坚韧不拔的毅力。", 34 | "Motivation is what gets you started. Habit is what keeps you going.\n\n动力使你开始,习惯让你坚持。", 35 | "Good habits, once established are just as hard to break as are bad habits.\n\n好习惯一旦养成了和坏习惯一样难以改掉。", 36 | "It does not matter how slowly you go as long as you do not stop.\n\n切勿画地为牢,裹足不前。", 37 | "Habits form character, decided the fate of character.\n\n习惯养成性格,性格决定命运。", 38 | "A creative man is motivated by the desire to achieve, not by the desire to beat others.\n一个有创造性的人的行为动力是取得成就,而不是为了打败别人。"}; 39 | 40 | private int imgIndex; 41 | 42 | private ImageView imageView; 43 | 44 | 45 | @Override 46 | protected void onCreate(Bundle savedInstanceState) { 47 | super.onCreate(savedInstanceState); 48 | setContentView(R.layout.activity_today_card); 49 | 50 | android.support.v7.widget.Toolbar toolbar = (android.support.v7.widget.Toolbar) findViewById(R.id.toolbar4); 51 | toolbar.setNavigationOnClickListener(new View.OnClickListener() { 52 | @Override 53 | public void onClick(View view) { 54 | finish(); 55 | } 56 | }); 57 | 58 | TextView tWeek = (TextView) findViewById(R.id.textView20); 59 | tWeek.setText(Utils.date2Week(new Date())); 60 | TextView tdate = (TextView) findViewById(R.id.textView22); 61 | String strDate = Utils.date2String(new Date()); 62 | String date = strDate.substring(0, 4) + "." + strDate.substring(4, 6) + "." + strDate.substring(6, 8); 63 | tdate.setText(date); 64 | TextView textView = (TextView) findViewById(R.id.textView23); 65 | Calendar cal = Calendar.getInstance(); 66 | int year = cal.get(Calendar.YEAR); 67 | LocalDate localDate = LocalDate.ofYearDay(year, 1); 68 | int dayCount = localDate.isLeapYear() ? 366 : 365; 69 | textView.setText("『 在" + year + "年剩余的" + (dayCount - cal.get(Calendar.DAY_OF_YEAR)) + "个日子里继续加油 』"); 70 | 71 | int day = cal.get(Calendar.DATE); 72 | imageView = (ImageView) findViewById(R.id.imageView4); 73 | byte[] image = getIntent().getByteArrayExtra("image"); 74 | if (image != null) 75 | imageView.setImageBitmap(BitmapFactory.decodeByteArray(image, 0, image.length)); 76 | else 77 | imageView.setImageResource(getResources().getIdentifier(img[day % 6], "drawable", getPackageName())); 78 | TextView textView1 = (TextView) findViewById(R.id.textView); 79 | textView1.setText(words[day % 6]); 80 | imgIndex = day % 6; 81 | 82 | } 83 | 84 | 85 | //  将布局转化为bitmap 86 | // 这里传入的是你要截的布局的根View 87 | public Bitmap getBitmapByView(View headerView) { 88 | int h = headerView.getHeight(); 89 | Bitmap bitmap = Bitmap.createBitmap(headerView.getWidth(), h, Bitmap.Config.ARGB_8888); 90 | Canvas canvas = new Canvas(bitmap); 91 | headerView.draw(canvas); 92 | return bitmap; 93 | } 94 | 95 | //把bitmap转化为file 96 | public File bitMap2File(Bitmap bitmap) { 97 | String path = ""; 98 | if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) { 99 | path = Environment.getExternalStorageDirectory() + File.separator;//保存到sd根目录下 100 | } 101 | 102 | // File f = new File(path, System.currentTimeMillis() + ".jpg"); 103 | File f = new File(path, Integer.valueOf(String.valueOf((new Date()).getTime() / 1000)) + ".jpg"); 104 | if (f.exists()) { 105 | f.delete(); 106 | } 107 | try { 108 | FileOutputStream out = new FileOutputStream(f); 109 | bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out); 110 | out.flush(); 111 | out.close(); 112 | bitmap.recycle(); 113 | } catch (FileNotFoundException e) { 114 | e.printStackTrace(); 115 | } catch (IOException e) { 116 | e.printStackTrace(); 117 | } finally { 118 | return f; 119 | } 120 | } 121 | 122 | public void shareCard(View view) { 123 | File file = bitMap2File(getBitmapByView(findViewById(R.id.constraintLayout5))); 124 | if (file != null && file.exists() && file.isFile()) { 125 | //由文件得到uri 126 | Uri imageUri = FileProvider.getUriForFile(getApplicationContext(), "com.example.habittest.fileprovider", file); 127 | Intent shareIntent = new Intent(); 128 | shareIntent.setAction(Intent.ACTION_SEND); 129 | shareIntent.putExtra(Intent.EXTRA_STREAM, imageUri); 130 | shareIntent.setType("image/*"); 131 | shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 132 | startActivity(Intent.createChooser(shareIntent, "分享图片")); 133 | } 134 | } 135 | 136 | public void changeCard(View view) { 137 | int i = Calendar.getInstance().get(Calendar.MILLISECOND) % 6; 138 | if (imgIndex == i) { 139 | imgIndex = (imgIndex + 1) % 6; 140 | } else { 141 | imgIndex = i; 142 | } 143 | imageView = (ImageView) findViewById(R.id.imageView4); 144 | imageView.setImageResource(getResources().getIdentifier(img[imgIndex], "drawable", getPackageName())); 145 | 146 | 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/habittest/Utils.java: -------------------------------------------------------------------------------- 1 | package com.example.habittest; 2 | 3 | import android.content.Context; 4 | import android.content.pm.PackageInfo; 5 | import android.content.pm.PackageManager; 6 | 7 | import java.util.Calendar; 8 | import java.util.Date; 9 | import java.util.List; 10 | 11 | public class Utils { 12 | private Utils() { 13 | } 14 | 15 | // 新浪微博是否安装 16 | public static boolean isSinaWeiboInstalled(Context context) { 17 | return isPackageInstalled(context, "com.sina.weibo"); 18 | } 19 | 20 | // 包名对应的App是否安装 21 | public static boolean isPackageInstalled(Context context, String packageName) { 22 | PackageManager packageManager = context.getPackageManager(); 23 | if (packageManager == null) 24 | return false; 25 | List packageInfoList = packageManager.getInstalledPackages(0); 26 | for (PackageInfo info : packageInfoList) { 27 | if (info.packageName.equals(packageName)) 28 | return true; 29 | } 30 | return false; 31 | } 32 | 33 | public static String date2String(Date date) { 34 | Calendar calendar = Calendar.getInstance(); //实例化calendar类 35 | calendar.setTime(date); ///更改为calendar类型 36 | int year = calendar.get(Calendar.YEAR); //单独获取年份 37 | int month1 = calendar.get(Calendar.MONTH) + 1; ////获取月份,格式存在不统一 06||6 38 | String month = String.format("%02d", month1); ///更改月份类型 39 | int day1 = calendar.get(Calendar.DAY_OF_MONTH); ///获取日,格式不统一 06||6 40 | String day = String.format("%02d", day1); //更改日期类型 41 | String date_s = year + month + day; ///合成8位String 42 | 43 | return date_s; 44 | } 45 | 46 | public static String date2Week(Date date) { 47 | String[] weekdays = {"周日", "周一", "周二", "周三", "周四", "周五", "周六"}; 48 | Calendar cal = Calendar.getInstance(); 49 | cal.setTime(date); 50 | int w = cal.get(Calendar.DAY_OF_WEEK) - 1; 51 | if (w < 0) w = 0; 52 | return weekdays[w]; 53 | } 54 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/card.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a9257/HabitDeveloping/2d913f1673dba1aa627ef2d4b1a6e19b35a6ca3d/app/src/main/res/drawable/card.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/card_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a9257/HabitDeveloping/2d913f1673dba1aa627ef2d4b1a6e19b35a6ca3d/app/src/main/res/drawable/card_1.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/card_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a9257/HabitDeveloping/2d913f1673dba1aa627ef2d4b1a6e19b35a6ca3d/app/src/main/res/drawable/card_2.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/card_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a9257/HabitDeveloping/2d913f1673dba1aa627ef2d4b1a6e19b35a6ca3d/app/src/main/res/drawable/card_3.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/card_4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a9257/HabitDeveloping/2d913f1673dba1aa627ef2d4b1a6e19b35a6ca3d/app/src/main/res/drawable/card_4.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/card_5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a9257/HabitDeveloping/2d913f1673dba1aa627ef2d4b1a6e19b35a6ca3d/app/src/main/res/drawable/card_5.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/card_6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a9257/HabitDeveloping/2d913f1673dba1aa627ef2d4b1a6e19b35a6ca3d/app/src/main/res/drawable/card_6.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/const_edge.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/habit_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a9257/HabitDeveloping/2d913f1673dba1aa627ef2d4b1a6e19b35a6ca3d/app/src/main/res/drawable/habit_1.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/habit_1_gray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a9257/HabitDeveloping/2d913f1673dba1aa627ef2d4b1a6e19b35a6ca3d/app/src/main/res/drawable/habit_1_gray.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/habit_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a9257/HabitDeveloping/2d913f1673dba1aa627ef2d4b1a6e19b35a6ca3d/app/src/main/res/drawable/habit_2.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/habit_2_gray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a9257/HabitDeveloping/2d913f1673dba1aa627ef2d4b1a6e19b35a6ca3d/app/src/main/res/drawable/habit_2_gray.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/habit_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a9257/HabitDeveloping/2d913f1673dba1aa627ef2d4b1a6e19b35a6ca3d/app/src/main/res/drawable/habit_3.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/habit_3_gray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a9257/HabitDeveloping/2d913f1673dba1aa627ef2d4b1a6e19b35a6ca3d/app/src/main/res/drawable/habit_3_gray.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/habit_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a9257/HabitDeveloping/2d913f1673dba1aa627ef2d4b1a6e19b35a6ca3d/app/src/main/res/drawable/habit_4.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/habit_4_gray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a9257/HabitDeveloping/2d913f1673dba1aa627ef2d4b1a6e19b35a6ca3d/app/src/main/res/drawable/habit_4_gray.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/habit_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a9257/HabitDeveloping/2d913f1673dba1aa627ef2d4b1a6e19b35a6ca3d/app/src/main/res/drawable/habit_5.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/habit_5_gray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a9257/HabitDeveloping/2d913f1673dba1aa627ef2d4b1a6e19b35a6ca3d/app/src/main/res/drawable/habit_5_gray.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/habit_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a9257/HabitDeveloping/2d913f1673dba1aa627ef2d4b1a6e19b35a6ca3d/app/src/main/res/drawable/habit_6.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_about_us.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a9257/HabitDeveloping/2d913f1673dba1aa627ef2d4b1a6e19b35a6ca3d/app/src/main/res/drawable/ic_about_us.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_all_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a9257/HabitDeveloping/2d913f1673dba1aa627ef2d4b1a6e19b35a6ca3d/app/src/main/res/drawable/ic_all_normal.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_all_select.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a9257/HabitDeveloping/2d913f1673dba1aa627ef2d4b1a6e19b35a6ca3d/app/src/main/res/drawable/ic_all_select.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_card.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a9257/HabitDeveloping/2d913f1673dba1aa627ef2d4b1a6e19b35a6ca3d/app/src/main/res/drawable/ic_card.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_dashboard_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_help.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a9257/HabitDeveloping/2d913f1673dba1aa627ef2d4b1a6e19b35a6ca3d/app/src/main/res/drawable/ic_help.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_home_1_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a9257/HabitDeveloping/2d913f1673dba1aa627ef2d4b1a6e19b35a6ca3d/app/src/main/res/drawable/ic_home_1_normal.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_home_1_select.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a9257/HabitDeveloping/2d913f1673dba1aa627ef2d4b1a6e19b35a6ca3d/app/src/main/res/drawable/ic_home_1_select.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_home_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165 | 170 | 171 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_menu_share.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a9257/HabitDeveloping/2d913f1673dba1aa627ef2d4b1a6e19b35a6ca3d/app/src/main/res/drawable/ic_menu_share.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_more_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a9257/HabitDeveloping/2d913f1673dba1aa627ef2d4b1a6e19b35a6ca3d/app/src/main/res/drawable/ic_more_normal.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_more_select.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a9257/HabitDeveloping/2d913f1673dba1aa627ef2d4b1a6e19b35a6ca3d/app/src/main/res/drawable/ic_more_select.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_notifications_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_over.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a9257/HabitDeveloping/2d913f1673dba1aa627ef2d4b1a6e19b35a6ca3d/app/src/main/res/drawable/ic_over.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_share.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a9257/HabitDeveloping/2d913f1673dba1aa627ef2d4b1a6e19b35a6ca3d/app/src/main/res/drawable/ic_share.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_sina.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a9257/HabitDeveloping/2d913f1673dba1aa627ef2d4b1a6e19b35a6ca3d/app/src/main/res/drawable/ic_sina.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a9257/HabitDeveloping/2d913f1673dba1aa627ef2d4b1a6e19b35a6ca3d/app/src/main/res/drawable/logo.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a9257/HabitDeveloping/2d913f1673dba1aa627ef2d4b1a6e19b35a6ca3d/app/src/main/res/drawable/plus.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/pure.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/select.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/shadow_date.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/shape.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 12 | 13 | 14 | 19 | 20 | 25 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/shape_1.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 18 | 19 | 24 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/shape_1_selected.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 18 | 19 | 24 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/shape_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 12 | 13 | 14 | 19 | 20 | 25 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/shape_2_selected.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 12 | 13 | 14 | 19 | 20 | 25 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/shape_finish.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 填充的颜色 6 | 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/shape_mine.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 填充的颜色 6 | 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/shape_selected.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 12 | 13 | 14 | 19 | 20 | 25 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/shape_time.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 12 | 13 | 14 | 19 | 20 | 25 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/sign_point.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 9 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/social_qq.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a9257/HabitDeveloping/2d913f1673dba1aa627ef2d4b1a6e19b35a6ca3d/app/src/main/res/drawable/social_qq.png -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_about_us.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 23 | 24 | 36 | 37 | 38 | 39 | 52 | 53 | 64 | 65 | 79 | 80 | 81 | 94 | 95 | 106 | 107 | 120 | 121 | 122 | 133 | 134 | 148 | 149 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_add_habit.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 21 | 22 | 32 | 33 |