3H*qJWi3FPB~HQ
z$Rk;!2y)M_ch}&**l|i%=Cfe-D&sxFec;k>a#}ByyDs{M=O%;z0uUk@a1o91W
zJQs+EQh#7fp-TbP>J)z%h+L;112`Hbt}dSN|Ws|(u?;u^b-
z8s2$bydKmZr(bgmeUI0Q(h?)Zs~S>6=0VbGofOwx$%nwj$RR!UdX>#?mk+j+B$2SM
zoK-^7uEI5Ctef02S&-{$oI~^Uf%yp-nd~ntu@a0080BZ%9;{NT0BksNTyF>NdVkJU
z1*&}K*iq}>AxJ{Ht}&<@-=OTQz>NH>bxzG-Q=mfJ1X8cFdt+Qf-O_(15EP75q1tpW
zkUM=1*B1h;r(CttjtC{yk~hteBr&>w(4B?A3*FpUK^IZnR;Se@xZFNb&XhTx-|-(d
z)YnpnL+TjjyA_RyTdRZ0-yWUJUOn!RqJtm6*P37M$A26wL`|Nbi^)u4$!o|sIUu5|
zE{6%?e-xf9bpn#KuYs}Cb{69`C>9=^Dxq}jZS;U_yC-xwWK2l;Warb_L(Jrcn~B?^
z?l1Y;_he76d@lx6w&TPR-cd1=yN|+)_ejsbAvXiff6lC{1*|ots@~)EJI!43>2bJq
z;&*9CaF)8S@?4PKJ-Mfmsb?39c
zzw0RMhK5J7dq{J~QHl0V3+*ag7?h3dG06%9%?1w0I<&@rz&$+;P=dRlZ4o`AtDrnn
zFaPo#`B{-z$Ahm?m9plj86gAioV;6zMcD)(27{9&ep|-O@sc}K9cY@i!lj%AZ$?$S
zra=Sm_=f9OcHU+~jst@p+x7IxZf(b%
zUk?7G=Z_u#O)*DuAbWUq;#u%d+tEQ|@JmrmO=JG~_5KYLPUsEZPH;T}J+|2C5jTGz
z*g9RP5dT9v!DJ5nLz#}^%d_W+{KMUA1S4&VRyRzIJhbygq(c+*WU1Qo=a|o1(#t-&
zCMPSWc3{AU41=Fc*N$?TFB=XB^drJ9;w&zJwf=`2hOV@uL|w`Kp-~(KjC#y
z1ls9scKs!M2;HP|*?m-gcyc85xYa74)aUC2SrR>vTJ671z?UxhqTf{h=gE=0IL$gW
zAqpL_1Uk!F9jJc|748Gmnvbtx`Q@&J9i6
zN_Tu~jcL1^twaE~)*g2usi#)pz6^n=s!d}JO04jRG&vEY@7*6sYHXbe>xv$DRzRuo
z=#B|Cshe0mIU2+U_{E(Eu`s);PoR6aT(e8+vKU4C41aj%Raff7FH-8&!_baI1=oj93i7cG3#9k>p^?*5mfK9fhKma~8&@n1h6~(dN|z#x-lfG8wm@LNajlLI*vEL6
zuA@}!vIxN;Od}L$EEoc+W;`FZ%d`weUcLCa9DZ$#{@k2SYrj<&RH2!mvuz!a
zU4z&87WC=t+5*b3f-g&Bf_c8r6hcRjah}E4v}esg&~o75U{;NsS0AFf?lpI5rE(Zq
zpu2NSkZb8nXIx3?JPZGv6p77F*VSaterBo?|GbERd4np
zBJC0`?8f<$#rGJU6=gG70rkADHcctrj9#E4geym8lgeQ3KBb!%ybq$IfmBj%%aOBC
z<8{b2Aqyd$pbnv!B1iz5MdOCQsHFPq_+eRgG;^&%NZmzia15G1|i_3PM
zuw*g$X}LM^&A0{HLLQo*U(;YXL|Mq+WZA8H29?2|$NCMubhJPa{7RM(jW$NEgE_+X_=KpM6Cxk{euG<0*uc8P{%Ec_>;#7K^v4ovC
z;FbO6IME6goHAmPXY#a70xJ7JTu?9(Iz%0EPwXOJ*?Qmpx`uwamdv2aMJOXfUq8i5
zvw%;z{$zPkbmYJZ{+G(LPmUEW${GjH9%DH;@Lt|7R!+0=*#P9+=8}r6qQF9}XWY>I
z2G2<>leJ`oRR6EKdo;L8Z-j(9jW=wTo+v2-6X-eBnN1Tn~^s`w)Wzy@Yx<*%Z
zX-ZqRH8(?CQ?}{>8k!G5w#L3R1TIBL>00*LfQc-TCR!VlKPtc3A9SGl$Sb$vSN_F~
zN=H#bT}iq@35G}Hmf$BEFS;$fYY3PgXlO3IuQq^_*G6Ul+CaoaIV?@>#6jxwE*(pn
z#FD$f#1gT>7j*01(c)xetRF42w+SWQ!gplV00OeYq?Mjn{gw9|VwM(j#(>utBcM+8
zEav8p*2U^J8(H!fNjkJ6F64ecj)4S7y4oQSR-nB@-H%u{ooY&Wgu8+)h{i^
z`sMmxiJH6T8zn7xYF|bWbRMwy&}#49JPA2EOv{(ocNssThF850w&IRYX%CJedZuz6
zq+DPQN#cK0qPr+&y|q~@=;jmb-vO#UV4fbL+LD{enw*@NCAJ({P@;sYp!EvU`E_=5
zG&Y~Ny1OX)zgA}?i5+38ltb#Fn)gtk18|~ThMNH_FFM~6C4v|&H{1!9V;V3WA&p;S
z>W`HdEil&&A(2Gb9FtDk8Bk3a
zlZD*K+})>n)SM%$m!GwH?tS{W)&7#FV>C$6p*QOF#J{D6XO?g2NJ30
zxuff>0!Z;x;*{IQERhqW;UAqU)x1oWe=|AA%ayJWVS-7;xeg*5)qc!U)wOFgnXNR8NxWd&AIci`OU;sV5=wWNjByz~_7^trL*1f?n(1un!qR{cl#
zb{BRCP}v{=HyXF$1z~~x=at9p)cZa4rdu?)fMO9l?l&WisKx?<7m?M!Q1D=-vN3As
zwBd3q>G2NV<7aIbnupsgQ16sW$%`CJ^+-ol5J^>nyTa?RO-r4LvjE0L^PKXQCdM;+
zvF2VWBUy!X2ZJIF^=O+$M=2Z=Z1LbIJI9Ka)1W#W+sYv!u{IxbqaiShMOX`bjl$L8
zs9?SioqADOLxce4Khew(9fqAMYf&oeB_et74stca$p&aQjm!c1F9_pr*OHy;-+`NKrXv73q-lfP9)S$chhe1msn
z)L!cJe0Q2Y03{f9e0y3xcp5|9Y)7Pk3iQI6
z{hF4AtUYl#IAdsi(q;nJwrMbRM&hujrVJK%Nh1;r^u3>0Z<7Vd4h7E+Lj9IiOF_X=
zG#1v%1gQ5jsB6k1IgcIaIXL4bZ0Th-r8b|xbY6sE5C3@@-Y@vNptzweuoG*FsdHcp
z^DVS~o=@-6wx+Q&OpCd&oBG|AskOcPFdtRPsS1IGT3#@$I)$4I@-f2SYhgOIHa^Ug
z!sD=m)6jy@s?2Kj<#2&J%u&%IPX4KGl#fPT0_;&Aw^hZJt>c24KpkkisfU>_I@twK3?c?RPXLM!CRh>1NX_i9Ar84@|e
z0du`H$FUp7OIB4N-^G+kLf;O!wp;-IJD;_`45FGyK4#%F!X7{E?~RVf;KeS8MMmD8
zh7C|)CX%QdujHg!oft?vgFvyIsyiKsLs7HD8xU&Y`enY~X0;F0LYi-IOiEytO|d=%
zA6a>W%;l$(Qi(+?@>j`i7&bp>U9l+$0KNn2K8NcE>2{YH+@Cae=D&Jzc5HV0;M}MA
z3M#;vx!?9EYLxxaH^9b3oH(hfzogc`XEPbh#~P~kBm;%=9r-mouaa+LjF$iVX7Ld72)oB
z+y3sbm)&$LWaF8+CHJhs_s{WslJ+_(yvdekcfydQ(&{%gI&c@KGI>Xzr>U;2shX&T
zfWj!I=xeZNC2;n@(<%^dGw)Jb2Ef3vzzG6CA)&|%gY~9EvgAguJf)XIQzYpxtx!q6
zaK%SmSiga@98Z!z?t)FK-SvbFIK7ZuY-1nmaCx+?cqJZaO(Bb=W?28FU!W+^8Q6HoFRRB
zXOK|#Dj)f-U82f`GPVEJ)G6amXL2j=bz|UTald(y_~keU5>76b5Ug2BF6OMO~aT5=!BeWK9m>j1ZE}|g@hW%P_8f~
zpYWA5Y=%p*hgVA{J5zoS+)M{@b6eC^`jp~F4ja>?en$Ub)yA0&?yHiAYMd95P41)y
z*&5gxUH4bH6v62Vo;xqH#?-Mh+zXXkJc%VCUys(@B}*qcSBsm52D?J_8JyBxP6cKd
zjRcK2)mg9@49^J5eszM+t=XnmS;gwaRC
z$iXLBz9I5nmUjh^{RW!0!sVkit%&f~;}VL=Ijg@K&`Vtr1w;e#AOb7EA@c;0uIpSc
zO0)GhgqV0)z++mUSOj}y89(0$f0F`LWmu_z`ZrDTe_$2D%
z_;9kx9wm~metN1+XH)J<7+mm{b<`Ya`EeRI$*55(a(cBMXQU;%o_FKlcvv9ai10yO
zcAn##8KeAu=FxhSJ|5C3vIZZfpIm<>WQU&x14`vD-{ilgHsB$nEFeJ>)`q2gJS4XB
z<>;60mk!^m0`7aHml!D0LS>X;iaM~1-;?-{kvj)L%mB8fL$}F`@ri2Uj?5Uv|it;RZ
zyj^c}jNV+W;~7?tY>DwmE;bUWoYUE^N`(e_v>>f3kS`Yh{p9M+pPDu&obI<>S9LxL
zHW4!oGsvFObo`&7xF;B)@#*S?mXOH}^X<3vPT&cYS+6~+w*Dwa@I2uf)1GtB9o?Q2
zFCC^8k6I~8N;o}1%urb_KuSOTK818>5fq4_=uJ$ej#p!^MuX7&4knWf&GogK-9;Ce
zVv8h0qQXhpSj5C$V%=5!57x}jEWYRmWI|XsyolvdDvIQljP3}BqSCGNirP*DfT7!^
z0F=FnN=*GP!*C9S&(bPMN^aygG1)k1mJ!KGWKm%EM6KT<(A0E_L9QPI?)Tm9UY9Nw
z5ja{(K`u~5_SkwRn**D|8AG|6ig<=$Ql#Y%54>b;bGeH2A`SCi3wge
ze~TK|{*#_Kk1SD4&hZxmMvAydLdhQ`5%9zopBDT!lNNpBy|%W}u5%u)Bm(kuReA8f
zT5;9xbN;kc`8i3w>C|6$7-Kz;LHH*`+>L2gE|qg8GZUwT(Ooijs5@bI>xCfpdx5l2B|EN|A@Fm6
zx;I+p9518wJY%VI?Sbfd7yu)RsNzg`7|yOKH~tyM#IOeMJJl%c%Uld%{oYE2x+hJl
zTVCQwfk%`hk--VbK~7N`chol}#`oFnQKOcqVnXV!p6*esrcGw#a!aBSa(Op@=lgej
zf?fy)k$Mas?To>92>*8nCE5`V$d6OBKZyT0G`xFqkLNEl{R}JnPE#SRE(Y45;e3(_nQ5N(z7|v0
z>{tVPlId8p_9(um3r+!8&n1$w=>(gv;AiIW)aX#J=_*!UpZ7V;iXU0H6yD_dKB
zBfj<5m8nn?&-&!Bd>;DMW7b-MQX_F0u`UgDl1jyQW)G+O#hV2fQn9&d3a?QE=+Kwg
zSnLT4t&ngiBN>h8?ISaj5m!UQbp3OyS)6GRESWlRHO+H6W|_^TmWSIN$VvJa1|!l6
zY*je2Ze-N`buAPK6Hzgrs64d038Tk07?3c8A<=VE2QRcHMv;L_km_i{TH@l2_3%X%
z=hpa863Igd$!&l=x}56NzuI;Z2?>$*_EiY=>+t8E7e>uUrd}MRX1ShWacC{3kL`mu
zc|li~c@>15f5#jKVfdhZX{6X~vL6HG#&q_6G
z%-u{(qW(2@k!Oe3AI0(LRF!lG+0)s+W&EUF^qm>9o@$ar9Sxbe9ZMCtae5HF(uIpt=9Cz~^E%JX6PkI`_sDS(GGxzv_HK$i
zKqa%iI=Z&K9IL2NR|(%LK5Z2F6x`8y6NJNyoBH;46z-S4GhzMGEQGMDegQf5&B5-h
zG42^%3DfG7ez2);IW-t#1OdF6MWeRKkx(v_Y$PnsQrTHC!l!zVhq(%a&@qR*L}I$g
zGLjNdHY#s*Q(Q^f`*>4H5awnmek_;b4zT&Cz)Ev{Uxa$p5sMgk33mY&u#-8=%5a
zr}obrR!qjDd&Bzl7vtYEQORuC-gsJ2nArec|Ld?pb&-XfwTZ(|+z8-S6%fR@&s|II
zCD)93nZ_f%Ih{)(5FloqgV}KIV02Lok*8n?Y}5{&Nj3NMK>8qZK#H=er}pnYHB828
ztj1C0Z^e#k8qS0Agb5f@7uB)((3w39cZbMRslHM#ziIZnfZ5ICE}Lxsa1Uo_1QZ%P
ze&Gy#;EhZlmK@Zvo=EN2v+BBcsQ%Pa(;-@u_1_JaH;!2{j+cuLkMco%~`>~ZSdme
zqY7ctSW8P9@Zg8_jO|NK{B~Ko_!zoN*3uRg0gP9x2hv8RoPrFO7&b8
zGdgruCh`px@+!dxN6gIo*w=}Ix$a^9&V{3%)!5C0={8Ld$Ov6
zmUsP?ZohZ@hcu?T2&~()o(GD3@rqMFJi64Ie=qQ~y1z^mwY@pXJcVRRJiS;hQ#;B^
zksu9q{S5K{2wX!_?9S=N`IF(5`Fmq$VH!6BEuUG$-F97{x(?MBl5eMJ4>nHVNhF
z;9*8899_{AzE)bpz+Ooo6&P>IQDn2E&=9tJ)7FM^rE!yx)KP>n9dK8J(yTBof<3Cj#X2VOtuxjP)*hn-0
zpJ0{k8XK1RPffI7)E2b20joe^F^xYf8(Td
z7`cnwrV-ZIrMyqhG$CT43x@72B=+=fo+B5Z7h>@|HecUQ<|K?@^4Q;^LY7i5VgG`1
zo@q*3;aauWOB>0%Ea$s-+~Q3RAb>S8C$HILc+<}voyBT6*&WU
z2rQ4GR4Q&k*WuFe>LIIreU|xysR}jVcG8_nQp|HEzZ}HkJGRZiHY?spm=
zPTrg5z4i|nEYVLfLX>#n+4JwMSEyWhuulFnj&_x=7CiQNi#8#zS?`5*e9**gx$^(U#e(aMJwi1iFCKUs0K5Eu!jsIi9nWkc*dPd
zILg6z!ceHM$S46c4LkL?H7ZUgQI2!q5xf)fS)BC2(`wF9GjqPC;i)Lid$U!7g#<5e
zZ&zyAz<}1o7lk|JD%R-*lB@f58wgcy?+3)P9L29wpy^jx!CI%y5F10&7R2{`KtKdg-!pfVlUCA-&anf
zonAlz;IT)72oKL;a!jFp!)161*5avYM}qMhuc4L!JnKM*J>?zxE}Q&UNH#N@$QyGNs{lT^=^fnuFNr
zA70v~qiYaQLf~bse2rZl(oJPV<}wR>^uJW6Cq%zcY)f9wnO!@&yZ2|eTW{lznyX;JOrJLb`h=?Wzz
zXarL5`6rV9w5ALZ7ETxUF%nGMsU${9za${XJNTw6#X|ipK+2zc2;0&}3<<9fLU#R-
zL&y0JK%)13WWRo44D@CS)FijU-i-nJfe$Ueh~D>So&I5xVNNI{e55-cynJg?Biu<1
zdJ7DrZqjLL*@Bv3(vufmlS`gd;rlLP{+hZ;ef#2qCDFc&eSAg*6Y-{rTCVRzRe>7z
zUFgwq7W%wG;finrdMFsW3QiwKy-XI_0Y|rqrtd7bk!|Yx#zjzDs`O-aZxcYk7fWPUmo5qnk6Q#JM+Y$>~V=;8MYC$o&gZMo7zdre2oQPKF4gwvWoPS&Ot73oFO
zbtc@y7Sv7eePXIADP^7y9o&t!|8f7E*YWghc88fPbZn-hsVI}-BZHV93iY@BMI8Rr
zx|mqhHnaN2IR8=GO==(@@?w2vcyQ}}|5o6mO1`>|0_%hKEh+u0xY=#VCq<(>D>Nisa^e?PD>JP2dYCzSs4YiKwvSqzCK<0v47njfubGh7
z%`mDOfzaQKg;DF>yEPBLq186z0Wq%^o(npk^&}fF^8j;R-V8whcdEXxbY*yk)WLey
z%`Uq=>&TUekfOKn8h0G;4MyZ3PSQ_eu?8EP3mWTcG^ILvI7{s7gum;}o*k{tb(V}Z
zs>=FPXjp9&M=nfqTi?B;mQO#ZSYV!8vx7w^#<^y29A`c?GQmJdO1A
z!dAuEQkXv|dB4CY2%jmSyAz(fdtw`;g+hFwDPS&3P-g*(XX{oF|1H|KR?=U@!@MCl
zR9TvyZX-ink`GK>%of}FEZf^;Up%w}bYdMLmhXX>Kl8bX=2K+cMx;hV=mRb?R$>FD
zn5)}g`m~!}sHm{^CRsL)jmflsp2SKT=grA9gYeKi`-XQ%$IqTWedvP
zsPF^xdJ|b-9rzgoTGZZ7{XR^&-W*9?uQIGsgrI~r;BiBVl$>w0kAi_XlC_&mB`D#J
z^lyJCwN5B&j_s#0(;uX;<+gqnMP>0y#xtRUA&mpox?nx=>1_|`M5csQTF|t3%YC=3
z?*6`M_J{i0;+)sYaG!O5QDRqR82RgUcUM-N=AG!T?H#u#`LhG769tXen3g%OF}ktq
zt&e9KFY{2uv`x2lIVpEaS2$3D`*PiYs371R&h4CRx9Zs`uIjF)XuI;LHTP<)!dD=?24Zp+YIv&m+%?~-Tg
zgY6VcnmkKz+Aw0qA@3R49sI%h9dw;-L{M1u+hY{*W1|i2ng*j&(90t?M9CZ4i}&VM
zmO;N-hsz^NclPLwA-);;-Wq7~q=2`HpUB0@!u_q;Jmt)Z2f2#5CpZB(_x04-g9gxs
z%Rqhbg0_D>AC)xfz8@ME$T+V1W*MuWXAgc|vmGXQ7Wa@9B_i}T#HE4e1VYh-9^M?5
zO06PzSjQ5u6JV#PDi})*N4U10Iapa5;+iTs_B;Ru0zq{JGC$@nvy)k*{hFeH1-e5ppOjvtJpH}_6B-NYSl~iwG$VUp
z=xRULA(nKgJK7eF?*k#n&_(=#+vWm8ujSEmEZFOPa
zUwu#=Poh8Gk$tic2awk8W1bbCdx(DyTGl`szg${%Xc86aarkDRy
z`7Ne54qnLpGO10BvvZJ*oU*HI@kEn44&32))DS!<__tO{msW-Xf^Ecm&_1x=;HCkZ
zx|Aw?r3UdDfwkagFozAYWZM8b806zmEst)DkF7Yadu&qgnJ8Q7#k(
z3t8X(SYcB(gSS2pzVBjBCsZBqgOCPqqU0hFT9qdcI-~F=m8(j0dt1>)0(v1z;fL2b
zkaV7?H^~G92UYvJ{V$U>ANoNIP^E0v1mR|n$I!w*v58{cMBx@aQdAdPqL+$V!t`DkwK~ijefz_Jkv%Rz#
znWtQe{B4L`T_ah!5Z_ZjY+f(x^iqi2%bM3Y*g=j0HIa(qwQ!%}0x(k|+K?jI5{eX&
z<>G-M!X&0?{qF4b5(9)?ns#B&nd%ocwbKNZEvxE$J(qU{hQL{XK$D7s-#mc#AVL{U
zQ1|cg9;8l=2a%QjOOxvN7!qPjIa5)0)o>6|s-6~qVYe-*U|;f;E$VFF;=b~lH(qtU
zOgQcyE9!mlCVKxV5{DZwdjs51{77f`8~GfL)R<)ZO$5Gc%>f=Nqm^o836^%qkE-
zy!PYG*%Kt-;4h$2+Ajuu=P#NM?XfK3wZy!+$wq_}^{M2%n&Q&?bJ_BU#OsUMRA*4=
z;yla8?UQ;_w|iQ$ZyBawd$T{_$~(}6HDh?C;u>csECbkOz}3+I;xF%`mS-WsjTlQ*
z7m=7}s0UsUS*-#!s1
zw0*+L{hx9X7|As!&u=5dTwjE@$wDN8vsfx&2yRa+P=)XFoDKQj`B{C4D
z{Rj^Rs4;0KN?>#8MPO4K{=!gb&c}=R9I%XE=f>g|G|f_pj>ekI!lfqrmFV1WwY)vG
zbO4p-7~WWXt;>apI?c6t&6O((ktFNGX6KLa($EPQ2)PrrO_dUHVI@wj+KAucaM8}0
zHZm=U|IRhe5)9-HE~a#st#
zQ^qi&FviSXFrgHnLyn_b`5*R8sQk>Z1@&B~C
zU59F5s0=>Fm4t4+Xi0dNo-gkCBTc6^z~pxfh3)OE4rR0dr%u-JuIaV;o9OQ`qR;2j
zQ~{|t1iv8om!wbAlA~s(8JIg+ftKW+c!@!=!2|d)pk^iwIpr&fHSA1i@?yeOjjs1>*z*^bEg;{R
z+k?^W-pP-G?eK3bxQw80WQ5T!3HL77iZ6f3f4wkV5WgT&METwjCXLBM;%Z?gLug*>
z(7e$Pg%AX1VgG*4bM6#blELNM4gM5E)hU?3ck~!kAc!F(wHF_(J|y7i{{uM5N{vo`
z8cf=2t~Z^+$j13?KswRt5lWF(5q8pQXI?cOYVy1DnYg|E)zq0U^TwODjd0E4G7G*F
z<5CE|3l8MXk;@gZ!I`5s437OS|36%{V6|!|)JB_F6aAvLXmUicYK^IEy
ze#Q0qcg?_2F!d`9jKjktbU14h9k*9&n$fey&^5dBXTx4HDF}}>Gr%3k#f$Q8Ps`4v
z4ZCk*`*G)j$x8{nR8f|j#Y6dXhJ>2}fvHLLc9|3t3dbf5EWqfS#>RpI99th8;qw5j
z{vDPsedn-~*JV=aiLjYCNfAc+mG7EqaQ3FRaWkYjr4}3E$@$
zu4OF>{W$1lvoYgh$p8YP93${uZ)w_)kw=7-9mVd6C&@BH$wg}?xeDO+-@qTUJIu
zD3w
znsv9T?B55Czm#iu&}qF=Yuj5@hd(vd`S6J@twE#IfuswAIvU0O9vN0(+dw@)xhd#l
zV-?G_nWYN<6zBNmks65D(i=|N+=+{T`>#fmV8l6qKfVyVtPc+@$ASH8wKEetkS})M
z^qP{*6NEA~4w&g38OCg`7jQ*UPm@MAUW`wn{G4PWuUNk{r!)1_X0G99FD-FNbMR_{
ztKOphuJBu9An?f+Wil3=N@AB`vc5Z
z`gL62GE~rkJuO3{36tdF`PLNEXvGSxVLYY*DW6FfJ22Wat^}2TULAakA3c^Cn?oI<
zAxkcfTIyU%yYCpRQDqR3&q4~`fu%;O&cbQ-q0?An6tN|b5^+e^*0J>U1C^$mF}kSJrKjS*CWejztHG2c&PuGrUl-vC;DB$oR1EX2;6dn2
z4^+?f$H*$b4r!g|o5|yFDVnptI5^K`657XsxRZ&q;4(nx9E_Ah5OK{cPcFp`%=}5^
zahUuq@yo{D9SpLI&{1yKcnKPbM^$jHGo+x}*<_JaAJUF4Xvb0_vO2dN1AhYPlWiVCYn
zO#Rar1ES17sbw8?3{*T~@DJ8FEGOo>Ly#m@GVNumaSMj>$EwA`ii#&j+FWvva&
zVGMlJYLd}xW!Cr8sg>nQgN3$rl8AB7Zn-h)YrMulmXU$%ZQZ9%=qj^2+xKDNsuKBz
z;P=%Ua;=L-N%o9eS@`42lsxBi=kteHda1@N`ZnUW!Zxu4$Tz~j=xUk=?cOf!7Ekoj
zae^E>^J)EicN?d`6CqR{Zrj$polWERr~GF~mS1%3g)?l~V?1!Zk;;?R{=v}Y1I{OE
zo1Oz?`SM$DW)qv=-*?6;OR0T#Sab0EL2%3oyu)nEGs=IP$u(sVWbWya{%xT!0=CV%
zJi`3uf^5MuLx~$zV_xgi+j_SVU9UjhV_DB>6R&`>nUMwHPIdnl+I*YfF>hxjpjQ4^
z;PrmxYY2aN$IRXNr-eCd&e$Aczx(vDzbE-cYWVg@0h6u&uHogm=C|TjL&3y;+hwfB
ze(X2t_qv4ddo)>fQ7N+)5!DuRxUk4BFf^IAgNN6%FP;a!EuQOnO7?uu|5lvYgR{?3^U-ah#`Q7GiGxN+j#RgkyI6!>7uk<_h}=!9x>j
zjxv(7Ww-S^R?2x7PijExFmunxn>P!Ijt57u6a0dz7B8u1(yhnWO)(WEe`{lX3)R%A
z=z9hGo`r%!xE~V2*+nU&J*hQaNTa&b!J{Jd7C0MU@USOPV0{=~f?~Ljd1t)J&MnS4
z*9R*em-l8TyzFYKI4@6eR}3Xg_cq|P`p-UC-vrgf_0OyM8t{c2l%x}uqyzeIfVC#+
zfD2l-T5v)R>4eP>fVa*MK%}^Y(Ir9t8&IuuNzkxSpeSh^gfK#2&p2rwgfJ|i_-U1d
zFlzsK=hGmFV0a+^^LnR=62Yi~Qm3U8!3co{rL7VDds8G0ff$Ah)Fw@w7={t=|8uW`
zfSezIfuQ~~ivRBd1tI=7tER;f!w7(ir%e;X@PoRfA&|hxfIS$bX_5R}O-)ND`S%g|
zv^f$OQBd(UZea;Qe2hHOT)HPFI>8`M-@z(yGW|_&`C@&dC4m
TPm@MU0YeS7NAS;>4f1~gW|*37
diff --git a/readme.md b/readme.md
deleted file mode 100644
index 4757b3d..0000000
--- a/readme.md
+++ /dev/null
@@ -1,2 +0,0 @@
-# Notes
-
From c4fe645595060acd0031e277cf9628568ea0155a Mon Sep 17 00:00:00 2001
From: gexinghai <2874903098@qq.com>
Date: Sun, 23 Apr 2023 17:59:31 +0800
Subject: [PATCH 3/7] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20READEME.md?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
README.md | 2 ++
1 file changed, 2 insertions(+)
create mode 100644 README.md
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..2989e2d
--- /dev/null
+++ b/README.md
@@ -0,0 +1,2 @@
+# 小米便签
+
From 4874b422e41459b5ef8a35ead974293955473dd5 Mon Sep 17 00:00:00 2001
From: gexinghai <2874903098@qq.com>
Date: Sun, 23 Apr 2023 18:00:19 +0800
Subject: [PATCH 4/7] =?UTF-8?q?=E5=88=A0=E9=99=A4=20.gitignore?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.gitignore | 117 -----------------------------------------------------
1 file changed, 117 deletions(-)
delete mode 100644 .gitignore
diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index 5bfdaf6..0000000
--- a/.gitignore
+++ /dev/null
@@ -1,117 +0,0 @@
-/src/Notes/app/build
-###Android###
-# Built application files
-*.apk
-*.ap_
-
-# Files for the ART/Dalvik VM
-*.dex
-
-# Java class files
-*.class
-
-# Generated files
-/src/Notes/app/bin/
-/src/Notes/app/gen/
-/src/Notes/app/out/
-
-# Gradle files
-/src/Notes/app/.gradle/
-/src/Notes/app/build/
-
-# Local configuration file (sdk path, etc)
-/src/Notes/app/local.properties
-
-# Proguard folder generated by Eclipse
-/src/Notes/app/proguard/
-
-# Log Files
-*.log
-
-# Crashlytics plugin (for Android Studio and IntelliJ)
-/src/Notes/app/com_crashlytics_export_strings.xml
-/src/Notes/app/crashlytics.properties
-/src/Notes/app/crashlytics-build.properties
-/src/Notes/app/fabric.properties
-
-# Android Studio Navigation editor temp files
-/src/Notes/app/.navigation/
-
-# Android Studio captures folder
-captures/
-
-# Keystore files
-*.jks
-
-# External native build folder generated in Android Studio 2.2 and later
-.externalNativeBuild
-
-###macOS###
-*.DS_Store
-.AppleDouble
-.LSOverride
-
-# Icon must end with two \r
-Icon
-
-
-# Thumbnails
-._*
-
-# Files that might appear in the root of a volume
-.DocumentRevisions-V100
-.fseventsd
-.Spotlight-V100
-.TemporaryItems
-.Trashes
-.VolumeIcon.icns
-.com.apple.timemachine.donotpresent
-
-# Directories potentially created on remote AFP share
-.AppleDB
-.AppleDesktop
-Network Trash Folder
-Temporary Items
-.apdisk
-
-###Linux###
-*~
-
-# temporary files which can be created if a process still has a handle open of a deleted file
-.fuse_hidden*
-
-# KDE directory preferences
-.directory
-
-# Linux trash folder which might appear on any partition or disk
-.Trash-*
-
-# .nfs files are created when an open file is removed but is still being accessed
-.nfs*
-
-###Windows###
-# Windows image file caches
-Thumbs.db
-ehthumbs.db
-
-# Folder config file
-Desktop.ini
-
-# Recycle Bin used on file shares
-$RECYCLE.BIN/
-
-# Windows Installer files
-*.cab
-*.msi
-*.msm
-*.msp
-
-# Windows shortcuts
-*.lnk
-###IntelliJ###
-*.iml
-*.ipr
-*.iws
-/src/Notes/app/.idea/
-/src/Notes/app/libs/
-/.idea
From 068b14af6df0dc37fc981ecf415d42e7b7ef4dd6 Mon Sep 17 00:00:00 2001
From: ZhaoJie <207594601@qq.com>
Date: Tue, 25 Apr 2023 22:37:41 +0800
Subject: [PATCH 5/7] =?UTF-8?q?=E8=B5=B5=E6=9D=B0ui=E5=8C=85=E6=B3=A8?=
=?UTF-8?q?=E9=87=8A?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../micode/notes/ui/AlarmAlertActivity.java | 9 ++
.../micode/notes/ui/AlarmInitReceiver.java | 3 +
.../net/micode/notes/ui/AlarmReceiver.java | 2 +
.../net/micode/notes/ui/DateTimePicker.java | 45 ++++++++--
.../micode/notes/ui/DateTimePickerDialog.java | 4 +
.../net/micode/notes/ui/DropdownMenu.java | 8 +-
.../micode/notes/ui/FoldersListAdapter.java | 5 ++
.../net/micode/notes/ui/NoteEditActivity.java | 68 ++++++++++----
.../net/micode/notes/ui/NoteEditText.java | 10 ++-
.../micode/notes/ui/NotesListActivity.java | 88 +++++++++++++------
.../net/micode/notes/ui/NotesListAdapter.java | 29 +++---
.../net/micode/notes/ui/NotesListItem.java | 1 +
.../notes/ui/NotesPreferenceActivity.java | 16 ++--
13 files changed, 211 insertions(+), 77 deletions(-)
diff --git a/src/Notes/app/src/main/java/net/micode/notes/ui/AlarmAlertActivity.java b/src/Notes/app/src/main/java/net/micode/notes/ui/AlarmAlertActivity.java
index 85723be..280ae78 100644
--- a/src/Notes/app/src/main/java/net/micode/notes/ui/AlarmAlertActivity.java
+++ b/src/Notes/app/src/main/java/net/micode/notes/ui/AlarmAlertActivity.java
@@ -60,6 +60,7 @@ public class AlarmAlertActivity extends Activity implements OnClickListener, OnD
| WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON
| WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR);
}
+// 在Activity创建时被调用,它首先设置Activity的特性,然后获取传递过来的Intent,从中获取提醒的ID和摘录信息,并根据提醒的ID判断提醒是否可以在Note数据库中找到,并显示对应的提醒对话框和播放提醒声音。
Intent intent = getIntent();
@@ -82,11 +83,14 @@ public class AlarmAlertActivity extends Activity implements OnClickListener, OnD
finish();
}
}
+// 以一个try-catch块开始,尝试从意图中提取一个笔记ID,使用笔记ID从内容提供程序中检索与该笔记相关的文本片段,并在文本片段太长时截断它。如果在此过程中抛出IllegalArgumentException异常,则捕获该异常并返回方法。
+//接下来的代码块创建一个新的MediaPlayer对象,并检查与笔记ID关联的笔记是否在笔记数据库中可见。如果可见,则调用名为showActionDialog()的方法,该方法可能显示一个对话框给用户。还调用了playAlarmSound()方法,该方法可能会播放警报声。如果笔记在数据库中不可见,则方法仅完成而不显示对话框或播放声音。
private boolean isScreenOn() {
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
return pm.isScreenOn();
}
+// 用于判断屏幕是否打开。
private void playAlarmSound() {
Uri url = RingtoneManager.getActualDefaultRingtoneUri(this, RingtoneManager.TYPE_ALARM);
@@ -118,6 +122,7 @@ public class AlarmAlertActivity extends Activity implements OnClickListener, OnD
e.printStackTrace();
}
}
+// 用于播放提醒声音,首先获取系统默认的闹铃铃声,然后判断当前是否为静音模式,如果是,则设置MediaPlayer的音频流类型为系统当前可影响铃声的流,否则设置为闹钟流类型。最后设置铃声数据源、循环播放并开始播放。
private void showActionDialog() {
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
@@ -129,6 +134,7 @@ public class AlarmAlertActivity extends Activity implements OnClickListener, OnD
}
dialog.show().setOnDismissListener(this);
}
+// 用于显示提醒对话框,其中包含提醒的摘录信息和两个按钮(确认和进入)。
public void onClick(DialogInterface dialog, int which) {
switch (which) {
@@ -142,11 +148,13 @@ public class AlarmAlertActivity extends Activity implements OnClickListener, OnD
break;
}
}
+// 用于处理对话框中按钮的点击事件,如果是进入按钮,则启动NoteEditActivity并携带提醒的ID,将它作为Extra参数传递给NoteEditActivity以便打开对应的Note。如果是确认按钮,则什么都不做。
public void onDismiss(DialogInterface dialog) {
stopAlarmSound();
finish();
}
+// 用于处理提醒对话框关闭事件,停止播放提醒声音并结束Activity。
private void stopAlarmSound() {
if (mPlayer != null) {
@@ -156,3 +164,4 @@ public class AlarmAlertActivity extends Activity implements OnClickListener, OnD
}
}
}
+// 用于停止播放提醒声音。
diff --git a/src/Notes/app/src/main/java/net/micode/notes/ui/AlarmInitReceiver.java b/src/Notes/app/src/main/java/net/micode/notes/ui/AlarmInitReceiver.java
index f221202..5b41fe2 100644
--- a/src/Notes/app/src/main/java/net/micode/notes/ui/AlarmInitReceiver.java
+++ b/src/Notes/app/src/main/java/net/micode/notes/ui/AlarmInitReceiver.java
@@ -28,6 +28,8 @@ import net.micode.notes.data.Notes;
import net.micode.notes.data.Notes.NoteColumns;
+//这里定义了一个包名为net.micode.notes.ui的Java类AlarmInitReceiver,它继承了BroadcastReceiver类。引入了Android系统提供的AlarmManager、PendingIntent、BroadcastReceiver、ContentUris等类。还引入了笔记相关的数据模型Notes和NoteColumns。
+//PROJECTION是笔记查询时的投影,指定了需要查询的列。COLUMN_ID和COLUMN_ALERTED_DATE则是笔记查询结果中对应的列索引。
public class AlarmInitReceiver extends BroadcastReceiver {
private static final String [] PROJECTION = new String [] {
@@ -62,4 +64,5 @@ public class AlarmInitReceiver extends BroadcastReceiver {
c.close();
}
}
+// onReceive方法是接收广播后执行的方法。在这里,首先获取当前时间戳currentDate,然后通过getContentResolver().query方法查询所有需要提醒的笔记,查询条件是提醒时间大于当前时间戳并且类型是笔记类型。
}
diff --git a/src/Notes/app/src/main/java/net/micode/notes/ui/AlarmReceiver.java b/src/Notes/app/src/main/java/net/micode/notes/ui/AlarmReceiver.java
index 54e503b..a485c43 100644
--- a/src/Notes/app/src/main/java/net/micode/notes/ui/AlarmReceiver.java
+++ b/src/Notes/app/src/main/java/net/micode/notes/ui/AlarmReceiver.java
@@ -27,4 +27,6 @@ public class AlarmReceiver extends BroadcastReceiver {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
+// onReceive方法中,首先获取传入的Intent对象,并通过setClass方法将Intent的目标Activity设置为AlarmAlertActivity。然后通过addFlags方法设置Intent的标志位FLAG_ACTIVITY_NEW_TASK,表示启动一个新的Task来显示Activity。最后通过context.startActivity方法启动Activity。
}
+//这段代码的作用是在系统闹钟触发时,启动AlarmAlertActivity来显示提醒内容。
\ No newline at end of file
diff --git a/src/Notes/app/src/main/java/net/micode/notes/ui/DateTimePicker.java b/src/Notes/app/src/main/java/net/micode/notes/ui/DateTimePicker.java
index 496b0cd..9440fe4 100644
--- a/src/Notes/app/src/main/java/net/micode/notes/ui/DateTimePicker.java
+++ b/src/Notes/app/src/main/java/net/micode/notes/ui/DateTimePicker.java
@@ -67,9 +67,9 @@ public class DateTimePicker extends FrameLayout {
private NumberPicker.OnValueChangeListener mOnDateChangedListener = new NumberPicker.OnValueChangeListener() {
@Override
public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
- mDate.add(Calendar.DAY_OF_YEAR, newVal - oldVal);
- updateDateControl();
- onDateTimeChanged();
+ mDate.add(Calendar.DAY_OF_YEAR, newVal - oldVal);// 使用Calendar类的add方法将mDate对象的日期字段(即Calendar.DAY_OF_YEAR)增加newVal - oldVal天,以更新日期。
+ updateDateControl();//调用updateDateControl方法,该方法用来更新日期控件的显示。
+ onDateTimeChanged();//调用onDateTimeChanged方法,该方法用来通知其他组件该日期时间已经发生了变化。
}
};
@@ -104,16 +104,20 @@ public class DateTimePicker extends FrameLayout {
isDateChanged = true;
}
}
+// 根据24小时制或12小时制以及上下午状态等情况,计算新的时间并更新到mDate字段中。
int newHour = mHourSpinner.getValue() % HOURS_IN_HALF_DAY + (mIsAm ? 0 : HOURS_IN_HALF_DAY);
mDate.set(Calendar.HOUR_OF_DAY, newHour);
onDateTimeChanged();
+// 调用onDateTimeChanged方法,该方法用来通知其他组件该日期时间已经发生了变化。
if (isDateChanged) {
setCurrentYear(cal.get(Calendar.YEAR));
setCurrentMonth(cal.get(Calendar.MONTH));
setCurrentDay(cal.get(Calendar.DAY_OF_MONTH));
}
+// 如果日期发生了变化,则调用setCurrentYear和setCurrentMonth方法更新年份和月份控件的显示。
}
};
+// 这段代码定义了一个监听器对象,用于监听小时NumberPicker控件的值变化事件。
private NumberPicker.OnValueChangeListener mOnMinuteChangedListener = new NumberPicker.OnValueChangeListener() {
@Override
@@ -126,6 +130,7 @@ public class DateTimePicker extends FrameLayout {
} else if (oldVal == minValue && newVal == maxValue) {
offset -= 1;
}
+// 当监听器被触发时,它首先根据 NumberPicker 的旧值和新值计算出一个 offset。如果旧值是最大值且新值是最小值,则将 offset 增加1。如果旧值是最小值且新值是最大值,则将 offset 减少1。
if (offset != 0) {
mDate.add(Calendar.HOUR_OF_DAY, offset);
mHourSpinner.setValue(getCurrentHour());
@@ -139,10 +144,13 @@ public class DateTimePicker extends FrameLayout {
updateAmPmControl();
}
}
+// 如果 offset 不为0,则监听器会更新 mDate 变量,将 offset 添加到小时数中,将小时选择器的值设置为当前小时,调用 updateDateControl() 更新日期控件,并根据新的小时数更新 AM/PM 控件。
mDate.set(Calendar.MINUTE, newVal);
onDateTimeChanged();
+// 更新 mDate 变量后,监听器将分钟值设置为新值,并调用 onDateTimeChanged() 通知任何监听器日期和时间已更新。
}
};
+// 定义了一个私有字段 mOnMinuteChangedListener,它是 NumberPicker.OnValueChangeListener 的一个实例。当表示分钟的 NumberPicker 的值发生变化时,此监听器将被触发。
private NumberPicker.OnValueChangeListener mOnAmPmChangedListener = new NumberPicker.OnValueChangeListener() {
@Override
@@ -156,12 +164,16 @@ public class DateTimePicker extends FrameLayout {
updateAmPmControl();
onDateTimeChanged();
}
+// 当监听器被触发时,它将 mIsAm 变量取反,表示用户选择了 AM 还是 PM。如果 mIsAm 是 true,则说明用户选择了 AM,此时监听器将 mDate 变量减去半天的小时数。如果 mIsAm 是 false,则说明用户选择了 PM,此时监听器将 mDate 变量加上半天的小时数。然后,监听器会调用 updateAmPmControl() 更新 AM/PM 控件,并调用 onDateTimeChanged() 通知任何监听器日期和时间已更新。
};
+// 定义了一个私有字段 mOnAmPmChangedListener,它是 NumberPicker.OnValueChangeListener 的一个实例。当表示 AM/PM 的 NumberPicker 的值发生变化时,此监听器将被触发。
public interface OnDateTimeChangedListener {
void onDateTimeChanged(DateTimePicker view, int year, int month,
int dayOfMonth, int hourOfDay, int minute);
+// 该接口有一个抽象方法 onDateTimeChanged(),它在日期或时间发生变化时被调用。该方法接收 6 个参数:view 表示当前 DateTimePicker 实例,year 表示年份,month 表示月份(从 0 开始),dayOfMonth 表示月中的某一天,hourOfDay 表示小时数(24 小时制),minute 表示分钟数。
}
+//定义了一个接口 OnDateTimeChangedListener,它用于监听日期和时间的变化。当日期或时间发生变化时,可以调用该接口的 onDateTimeChanged() 方法通知任何实现该接口的监听器。通过实现该接口并在需要的地方注册监听器,可以在日期或时间发生变化时执行自定义操作,例如更新 UI 或执行某些计算。
public DateTimePicker(Context context) {
this(context, System.currentTimeMillis());
@@ -173,15 +185,18 @@ public class DateTimePicker extends FrameLayout {
public DateTimePicker(Context context, long date, boolean is24HourView) {
super(context);
+
mDate = Calendar.getInstance();
mInitialising = true;
mIsAm = getCurrentHourOfDay() >= HOURS_IN_HALF_DAY;
inflate(context, R.layout.datetime_picker, this);
+// 首先调用了父类 ViewGroup 的构造函数 super(context) 来初始化 DateTimePicker 实例。然后,代码使用 Calendar.getInstance() 获取一个 Calendar 对象,该对象表示当前日期和时间。变量 mIsAm 被初始化为当前小时数是否大于等于 12,以确定当前用户选择的是 AM 还是 PM。
mDateSpinner = (NumberPicker) findViewById(R.id.date);
mDateSpinner.setMinValue(DATE_SPINNER_MIN_VAL);
mDateSpinner.setMaxValue(DATE_SPINNER_MAX_VAL);
mDateSpinner.setOnValueChangedListener(mOnDateChangedListener);
+// 获取了布局文件中 ID 为 date 的 NumberPicker 控件,并将其赋值给 mDateSpinner 变量。然后,使用 setMinValue() 和 setMaxValue() 方法将 mDateSpinner 的最小值和最大值分别设置为 DATE_SPINNER_MIN_VAL 和 DATE_SPINNER_MAX_VAL。使用 setOnValueChangedListener() 方法将 mDateSpinner 的值更改监听器设置为 mOnDateChangedListener。这意味着当 mDateSpinner 的值更改时,将会调用 mOnDateChangedListener 中的方法来处理这个事件。
mHourSpinner = (NumberPicker) findViewById(R.id.hour);
mHourSpinner.setOnValueChangedListener(mOnHourChangedListener);
@@ -190,13 +205,18 @@ public class DateTimePicker extends FrameLayout {
mMinuteSpinner.setMaxValue(MINUT_SPINNER_MAX_VAL);
mMinuteSpinner.setOnLongPressUpdateInterval(100);
mMinuteSpinner.setOnValueChangedListener(mOnMinuteChangedListener);
+// 获取了布局文件中 ID 为 hour 和 minute 的 NumberPicker 控件,并将它们分别赋值给 mHourSpinner 和 mMinuteSpinner 变量。然后,使用 setOnValueChangedListener() 方法将 mHourSpinner 和 mMinuteSpinner 控件的值更改监听器分别设置为 mOnHourChangedListener 和 mOnMinuteChangedListener。
+// 接下来,使用 setMinValue() 和 setMaxValue() 方法将 mMinuteSpinner 的最小值和最大值分别设置为 MINUT_SPINNER_MIN_VAL 和 MINUT_SPINNER_MAX_VAL,以限制分钟选择器的范围。
+// 最后,使用 setOnLongPressUpdateInterval() 方法将 mMinuteSpinner 的长按更新间隔设置为 100 毫秒。这意味着当用户长按 mMinuteSpinner 中的增加或减少按钮时,它将以每 100 毫秒的速度连续增加或减少 mMinuteSpinner 的值。
+// 通过设置 NumberPicker 的值更改监听器和其他属性,代码实现了一个可以选择小时和分钟的控件,并将它们分别绑定到 mHourSpinner 和 mMinuteSpinner 变量上,以便在之后的操作中使用。
- String[] stringsForAmPm = new DateFormatSymbols().getAmPmStrings();
+ String[] stringsForAmPm = new DateFormatSymbols().getAmPmStrings();//获取了当前设备的日期格式符号,并使用 getAmPmStrings() 方法从中获取 AM/PM 格式符号的字符串数组,并将其赋值给 stringsForAmPm 变量。
mAmPmSpinner = (NumberPicker) findViewById(R.id.amPm);
mAmPmSpinner.setMinValue(AMPM_SPINNER_MIN_VAL);
mAmPmSpinner.setMaxValue(AMPM_SPINNER_MAX_VAL);
- mAmPmSpinner.setDisplayedValues(stringsForAmPm);
- mAmPmSpinner.setOnValueChangedListener(mOnAmPmChangedListener);
+// 获取了布局文件中 ID 为 amPm 的 NumberPicker 控件,并将其赋值给 mAmPmSpinner 变量。使用 setMinValue() 和 setMaxValue() 方法将 mAmPmSpinner 的最小值和最大值分别设置为 AMPM_SPINNER_MIN_VAL 和 AMPM_SPINNER_MAX_VAL,以限制 AM/PM 选择器的范围。
+ mAmPmSpinner.setDisplayedValues(stringsForAmPm);//使用 setDisplayedValues() 方法将 stringsForAmPm 数组设置为 mAmPmSpinner 的显示值。这意味着 AM/PM 选择器将显示 stringsForAmPm 数组中的字符串,而不是默认的数字值。
+ mAmPmSpinner.setOnValueChangedListener(mOnAmPmChangedListener);//使用 setOnValueChangedListener() 方法将 mAmPmSpinner 的值更改监听器设置为 mOnAmPmChangedListener。这意味着当用户更改 AM/PM 选择器的值时,将调用 mOnAmPmChangedListener 中的方法来处理这个事件。
// update controls to initial state
updateDateControl();
@@ -204,6 +224,7 @@ public class DateTimePicker extends FrameLayout {
updateAmPmControl();
set24HourView(is24HourView);
+// 代码调用了 updateDateControl()、updateHourControl() 和 updateAmPmControl() 方法,以便将控件显示为当前日期和时间的值。然后,代码调用了 set24HourView() 方法将选择器的时间格式设置为 24 小时制或 12 小时制。
// set to current time
setCurrentDate(date);
@@ -212,6 +233,7 @@ public class DateTimePicker extends FrameLayout {
// set the content descriptions
mInitialising = false;
+// 调用了 setCurrentDate() 方法将选择器的日期和时间设置为指定的日期和时间,调用 setEnabled() 方法将选择器的可用状态设置为指定的值,并将 mInitialising 标志设置为 false,以便通知选择器已完成初始化。
}
@Override
@@ -219,13 +241,17 @@ public class DateTimePicker extends FrameLayout {
if (mIsEnabled == enabled) {
return;
}
+// 当调用 setEnabled() 方法时,如果传入的参数 enabled 与当前的 mIsEnabled 变量的值相同,说明选择器的可用状态没有发生变化,直接返回即可。
super.setEnabled(enabled);
mDateSpinner.setEnabled(enabled);
mMinuteSpinner.setEnabled(enabled);
mHourSpinner.setEnabled(enabled);
mAmPmSpinner.setEnabled(enabled);
mIsEnabled = enabled;
+// 代码首先调用父类的 setEnabled() 方法,将整个时间选择器的可用状态设置为传入的参数 enabled。然后,分别调用 mDateSpinner、mMinuteSpinner、mHourSpinner 和 mAmPmSpinner 的 setEnabled() 方法,将它们的可用状态也设置为传入的参数 enabled。
+//最后,将 mIsEnabled 变量的值设置为传入的参数 enabled,以便在下一次调用 setEnabled() 方法时使用。
}
+// 重写 setEnabled() 方法,代码实现了一个可以同时设置整个时间选择器的可用状态的功能。
@Override
public boolean isEnabled() {
@@ -428,11 +454,14 @@ public class DateTimePicker extends FrameLayout {
}
mIs24HourView = is24HourView;
mAmPmSpinner.setVisibility(is24HourView ? View.GONE : View.VISIBLE);
+// 当传入的参数 is24HourView 与当前的 mIs24HourView 变量的值相同时,方法直接返回。否则,将 mIs24HourView 变量的值设置为传入的参数 is24HourView,表示时间选择器的显示格式已经更改。
int hour = getCurrentHourOfDay();
updateHourControl();
setCurrentHour(hour);
updateAmPmControl();
+// 获取当前的小时数并调用 updateHourControl() 方法更新小时选择器,以保持小时选择器的一致性。接着,使用 setCurrentHour() 方法将当前的小时数设置回时间选择器,并调用 updateAmPmControl() 方法更新 AM/PM 选择器。
}
+//通过设置 AM/PM 选择器的可见性和更新时间选择器的小时控件和 AM/PM 控件,代码实现了一个可以切换时间选择器显示格式的功能。
private void updateDateControl() {
Calendar cal = Calendar.getInstance();
@@ -447,6 +476,8 @@ public class DateTimePicker extends FrameLayout {
mDateSpinner.setValue(DAYS_IN_ALL_WEEK / 2);
mDateSpinner.invalidate();
}
+// 用于更新日期选择器的显示值。它首先获取当前日期并将其设置为日历实例 cal 的时间。然后,cal 被设置为一周的第一天,以确保日期选择器显示一周的日期。
+//接下来,使用 setDisplayedValues() 方法将日期选择器的显示值设置为 null,以便重新生成新的日期显示值。然后,使用循环从 cal 中获取每一天的日期,并将其格式化为 MM.dd EEEE 的格式,并将其存储在一个字符串数组中。最后,使用 setDisplayedValues() 方法将新的日期显示值设置为 mDateSpinner,并将当前选择的日期值设置为一周的中间值,以保持日期选择器的一致性。
private void updateAmPmControl() {
if (mIs24HourView) {
@@ -457,6 +488,7 @@ public class DateTimePicker extends FrameLayout {
mAmPmSpinner.setVisibility(View.VISIBLE);
}
}
+// 用于更新 AM/PM 选择器的显示值。如果时间选择器为 24 小时格式,则将 AM/PM 选择器隐藏;否则,根据当前是否为 AM,将 AM/PM 选择器的值设置为 Calendar.AM 或 Calendar.PM,并将其可见性设置为 View.VISIBLE。
private void updateHourControl() {
if (mIs24HourView) {
@@ -467,6 +499,7 @@ public class DateTimePicker extends FrameLayout {
mHourSpinner.setMaxValue(HOUR_SPINNER_MAX_VAL_12_HOUR_VIEW);
}
}
+// 用于更新小时选择器的显示值。如果时间选择器为 24 小时格式,则将小时选择器的最小值和最大值分别设置为 HOUR_SPINNER_MIN_VAL_24_HOUR_VIEW 和 HOUR_SPINNER_MAX_VAL_24_HOUR_VIEW;否则,将小时选择器的最小值和最大值分别设置为 HOUR_SPINNER_MIN_VAL_12_HOUR_VIEW 和 HOUR_SPINNER_MAX_VAL_12_HOUR_VIEW。
/**
* Set the callback that indicates the 'Set' button has been pressed.
diff --git a/src/Notes/app/src/main/java/net/micode/notes/ui/DateTimePickerDialog.java b/src/Notes/app/src/main/java/net/micode/notes/ui/DateTimePickerDialog.java
index 2c47ba4..a7c67ce 100644
--- a/src/Notes/app/src/main/java/net/micode/notes/ui/DateTimePickerDialog.java
+++ b/src/Notes/app/src/main/java/net/micode/notes/ui/DateTimePickerDialog.java
@@ -39,6 +39,7 @@ public class DateTimePickerDialog extends AlertDialog implements OnClickListener
public interface OnDateTimeSetListener {
void OnDateTimeSet(AlertDialog dialog, long date);
}
+// 实现了一个 OnDateTimeSetListener 接口,该接口定义了一个 OnDateTimeSet() 方法,用于在用户选择日期时间后通知调用者。
public DateTimePickerDialog(Context context, long date) {
super(context);
@@ -55,6 +56,7 @@ public class DateTimePickerDialog extends AlertDialog implements OnClickListener
updateTitle(mDate.getTimeInMillis());
}
});
+// 包含了一个 DateTimePicker 控件,用于让用户选择日期和时间。通过 mDateTimePicker.setOnDateTimeChangedListener() 方法,当用户选择日期和时间时,将更新 mDate 的值,并使用 updateTitle() 方法更新对话框的标题。
mDate.setTimeInMillis(date);
mDate.set(Calendar.SECOND, 0);
mDateTimePicker.setCurrentDate(mDate.getTimeInMillis());
@@ -67,6 +69,7 @@ public class DateTimePickerDialog extends AlertDialog implements OnClickListener
public void set24HourView(boolean is24HourView) {
mIs24HourView = is24HourView;
}
+//set24HourView() 方法,用于设置日期时间选择器是否为 24 小时格式。默认情况下,该值将由系统的设置决定。
public void setOnDateTimeSetListener(OnDateTimeSetListener callBack) {
mOnDateTimeSetListener = callBack;
@@ -86,5 +89,6 @@ public class DateTimePickerDialog extends AlertDialog implements OnClickListener
mOnDateTimeSetListener.OnDateTimeSet(this, mDate.getTimeInMillis());
}
}
+// 重写了 onClick() 方法,以便在用户点击“确定”按钮后,将用户选择的日期时间作为参数传递到 OnDateTimeSet() 方法中,从而通知调用者。
}
\ No newline at end of file
diff --git a/src/Notes/app/src/main/java/net/micode/notes/ui/DropdownMenu.java b/src/Notes/app/src/main/java/net/micode/notes/ui/DropdownMenu.java
index 613dc74..44cca84 100644
--- a/src/Notes/app/src/main/java/net/micode/notes/ui/DropdownMenu.java
+++ b/src/Notes/app/src/main/java/net/micode/notes/ui/DropdownMenu.java
@@ -31,6 +31,7 @@ public class DropdownMenu {
private Button mButton;
private PopupMenu mPopupMenu;
private Menu mMenu;
+// 一个 Button 控件,用于显示菜单的标题,以及一个 PopupMenu 对象,用于显示菜单项。在构造函数中,该类接受一个菜单资源 ID,并使用 mPopupMenu.getMenuInflater().inflate() 方法从 XML 资源中加载菜单项,然后将菜单项添加到 mMenu 对象中。
public DropdownMenu(Context context, Button button, int menuId) {
mButton = button;
@@ -43,19 +44,22 @@ public class DropdownMenu {
mPopupMenu.show();
}
});
+// 重写了 setOnClickListener() 方法,以便在用户点击 Button 控件时显示下拉菜单。
}
+// 在 Button 控件上注册一个单击事件监听器,并在该监听器中实现下拉菜单的显示逻辑。
public void setOnDropdownMenuItemClickListener(OnMenuItemClickListener listener) {
if (mPopupMenu != null) {
mPopupMenu.setOnMenuItemClickListener(listener);
}
}
+// setOnDropdownMenuItemClickListener() 方法,用于设置菜单项的点击监听器。通过这个方法,应用程序可以在用户选择菜单项时执行相应的操作。
public MenuItem findItem(int id) {
return mMenu.findItem(id);
- }
+ }//findItem() 方法用于查找指定 ID 的菜单项
public void setTitle(CharSequence title) {
mButton.setText(title);
- }
+ }//用于设置菜单的标题。
}
diff --git a/src/Notes/app/src/main/java/net/micode/notes/ui/FoldersListAdapter.java b/src/Notes/app/src/main/java/net/micode/notes/ui/FoldersListAdapter.java
index 96b77da..71a4f49 100644
--- a/src/Notes/app/src/main/java/net/micode/notes/ui/FoldersListAdapter.java
+++ b/src/Notes/app/src/main/java/net/micode/notes/ui/FoldersListAdapter.java
@@ -47,6 +47,7 @@ public class FoldersListAdapter extends CursorAdapter {
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return new FolderListItem(context);
}
+// 用于创建新的视图,该方法返回一个新的 FolderListItem 对象,它是一个自定义的 LinearLayout,用于显示文件夹列表项的布局。
@Override
public void bindView(View view, Context context, Cursor cursor) {
@@ -56,12 +57,14 @@ public class FoldersListAdapter extends CursorAdapter {
((FolderListItem) view).bind(folderName);
}
}
+// 用于绑定视图和数据,该方法会将数据从 Cursor 对象中读取出来,并将其绑定到 FolderListItem 视图中。
public String getFolderName(Context context, int position) {
Cursor cursor = (Cursor) getItem(position);
return (cursor.getLong(ID_COLUMN) == Notes.ID_ROOT_FOLDER) ? context
.getString(R.string.menu_move_parent_folder) : cursor.getString(NAME_COLUMN);
}
+// 获取文件夹列表中某个位置的文件夹名称。
private class FolderListItem extends LinearLayout {
private TextView mName;
@@ -76,5 +79,7 @@ public class FoldersListAdapter extends CursorAdapter {
mName.setText(name);
}
}
+// FolderListItem 类是一个自定义的 LinearLayout,用于显示文件夹列表项的布局。它包含一个 TextView 控件,用于显示文件夹名称。
}
+//这段代码是一个自定义的 CursorAdapter 类 FoldersListAdapter,用于在 Android 应用程序中显示一个文件夹列表。
diff --git a/src/Notes/app/src/main/java/net/micode/notes/ui/NoteEditActivity.java b/src/Notes/app/src/main/java/net/micode/notes/ui/NoteEditActivity.java
index 387c03a..93df003 100644
--- a/src/Notes/app/src/main/java/net/micode/notes/ui/NoteEditActivity.java
+++ b/src/Notes/app/src/main/java/net/micode/notes/ui/NoteEditActivity.java
@@ -63,7 +63,6 @@ import net.micode.notes.tool.ResourceParser.TextAppearanceResources;
import net.micode.notes.ui.DateTimePickerDialog.OnDateTimeSetListener;
import net.micode.notes.ui.NoteEditText.OnTextViewChangeListener;
import net.micode.notes.widget.NoteWidgetProvider_2x;
-import net.micode.notes.widget.NoteWidgetProvider_3x;
import net.micode.notes.widget.NoteWidgetProvider_4x;
import java.util.HashMap;
@@ -84,6 +83,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
public ImageView ibSetBgColor;
}
+// HeadViewHolder类定义了一组视图,用于在列表或网格中显示信息。这些视图包括一个TextView用于显示修改信息,一个ImageView用于显示警报图标,另一个TextView用于显示警报日期,还有一个ImageView用于选择背景颜色。
private static final Map sBgSelectorBtnsMap = new HashMap();
static {
@@ -102,6 +102,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
sBgSelectorSelectionMap.put(ResourceParser.GREEN, R.id.iv_bg_green_select);
sBgSelectorSelectionMap.put(ResourceParser.WHITE, R.id.iv_bg_white_select);
}
+// sBgSelectorBtnsMap是一个HashMap,将用于选择背景颜色的ImageView视图的资源ID映射到整数值,这些整数值在ResourceParser类中定义。同样,sBgSelectorSelectionMap将整数值映射到所选ImageView视图的资源ID。
private static final Map sFontSizeBtnsMap = new HashMap();
static {
@@ -118,6 +119,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
sFontSelectorSelectionMap.put(ResourceParser.TEXT_MEDIUM, R.id.iv_medium_select);
sFontSelectorSelectionMap.put(ResourceParser.TEXT_SUPER, R.id.iv_super_select);
}
+// sFontSizeBtnsMap将用于选择字体大小的LinearLayout视图的资源ID映射到整数值,而sFontSelectorSelectionMap将整数值映射到所选ImageView视图的资源ID。
private static final String TAG = "NoteEditActivity";
@@ -185,10 +187,14 @@ public class NoteEditActivity extends Activity implements OnClickListener,
* If the user specified the {@link Intent#ACTION_VIEW} but not provided with id,
* then jump to the NotesListActivity
*/
- mWorkingNote = null;
+// 果用户指定了 Intent.ACTION_VIEW 动作但没有提供ID,则跳转到 NotesListActivity
+ mWorkingNote = null;//在方法中,首先将mWorkingNote设置为null。然后,根据传入的Intent的动作(action)进行选择。
if (TextUtils.equals(Intent.ACTION_VIEW, intent.getAction())) {
+// Intent中获取笔记ID
long noteId = intent.getLongExtra(Intent.EXTRA_UID, 0);
+ // 将用户查询字符串设置为空
mUserQuery = "";
+ // 如果Intent包含了搜索结果的额外数据,则从额外数据中获取笔记ID,并将用户查询字符串设置为搜索管理器中的用户查询字符串
/**
* Starting from the searched result
@@ -198,6 +204,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
mUserQuery = intent.getStringExtra(SearchManager.USER_QUERY);
}
+ // 如果笔记在笔记数据库中不存在,则跳转到 NotesListActivity 并显示错误信息的Toast,最后结束 Activity 并返回 false
if (!DataUtils.visibleInNoteDatabase(getContentResolver(), noteId, Notes.TYPE_NOTE)) {
Intent jump = new Intent(this, NotesListActivity.class);
startActivity(jump);
@@ -205,6 +212,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
finish();
return false;
} else {
+ // 加载笔记
mWorkingNote = WorkingNote.load(this, noteId);
if (mWorkingNote == null) {
Log.e(TAG, "load note failed with note id" + noteId);
@@ -212,11 +220,12 @@ public class NoteEditActivity extends Activity implements OnClickListener,
return false;
}
}
+// 如果该Intent的动作(action)为Intent.ACTION_VIEW,则从该Intent中获取笔记的ID(noteId)。如果该Intent还包含了一个搜索结果(Search)的额外数据(extra data key),则将noteId从额外数据中获取,并将用户查询字符串(mUserQuery)设置为搜索管理器中的用户查询字符串(SearchManager.USER_QUERY)。如果noteId在笔记数据库中不存在,则将Activity转到NotesListActivity,并显示一个错误信息的Toast,最后结束Activity并返回false。如果noteId在笔记数据库中存在,则加载该笔记的工作副本(mWorkingNote),如果加载失败,则结束Activity并返回false。
getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN
| WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
} else if(TextUtils.equals(Intent.ACTION_INSERT_OR_EDIT, intent.getAction())) {
- // New note
+ // New note 如果用户指定了 Intent.ACTION_INSERT_OR_EDIT 动作,则获取笔记ID,如果笔记ID存在,则加载笔记,否则,创建一个新的笔记
long folderId = intent.getLongExtra(Notes.INTENT_EXTRA_FOLDER_ID, 0);
int widgetId = intent.getIntExtra(Notes.INTENT_EXTRA_WIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID);
@@ -270,20 +279,26 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}
private void initNoteScreen() {
+ // 使用mFontSizeId设置笔记编辑器的文本外观。
mNoteEditor.setTextAppearance(this, TextAppearanceResources
.getTexAppearanceResource(mFontSizeId));
+ // 如果mWorkingNote的CheckListMode为TextNote.MODE_CHECK_LIST,则将编辑器转换为列表模式。
if (mWorkingNote.getCheckListMode() == TextNote.MODE_CHECK_LIST) {
switchToListMode(mWorkingNote.getContent());
} else {
+ // 如果mWorkingNote的CheckListMode不是TextNote.MODE_CHECK_LIST,则在编辑器中显示笔记内容,并使用mUserQuery高亮显示查询结果。
mNoteEditor.setText(getHighlightQueryResult(mWorkingNote.getContent(), mUserQuery));
mNoteEditor.setSelection(mNoteEditor.getText().length());
}
+ // 隐藏背景选择器中所有不在sBgSelectorSelectionMap中的ID的视图。
for (Integer id : sBgSelectorSelectionMap.keySet()) {
findViewById(sBgSelectorSelectionMap.get(id)).setVisibility(View.GONE);
}
+ // 设置mHeadViewPanel和mNoteEditorPanel的背景颜色为mWorkingNote的标题背景ID和背景颜色ID。
mHeadViewPanel.setBackgroundResource(mWorkingNote.getTitleBgResId());
mNoteEditorPanel.setBackgroundResource(mWorkingNote.getBgColorResId());
+ // 在标题栏中显示修改日期。
mNoteHeaderHolder.tvModified.setText(DateUtils.formatDateTime(this,
mWorkingNote.getModifiedDate(), DateUtils.FORMAT_SHOW_DATE
| DateUtils.FORMAT_NUMERIC_DATE | DateUtils.FORMAT_SHOW_TIME
@@ -297,6 +312,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}
private void showAlertHeader() {
+ // 如果mWorkingNote具有闹钟提醒,则检查当前时间是否超过提醒时间,如果超过,则在标题栏中显示“note_alert_expired”文本;否则,在标题栏中显示相对时间。
if (mWorkingNote.hasClockAlert()) {
long time = System.currentTimeMillis();
if (time > mWorkingNote.getAlertDate()) {
@@ -305,9 +321,11 @@ public class NoteEditActivity extends Activity implements OnClickListener,
mNoteHeaderHolder.tvAlertDate.setText(DateUtils.getRelativeTimeSpanString(
mWorkingNote.getAlertDate(), time, DateUtils.MINUTE_IN_MILLIS));
}
+ // 将标题栏中的提醒日期文本和提醒图标设置为可见。
mNoteHeaderHolder.tvAlertDate.setVisibility(View.VISIBLE);
mNoteHeaderHolder.ivAlertIcon.setVisibility(View.VISIBLE);
} else {
+ // 如果mWorkingNote没有闹钟提醒,则将标题栏中的提醒日期文本和提醒图标设置为不可见。
mNoteHeaderHolder.tvAlertDate.setVisibility(View.GONE);
mNoteHeaderHolder.ivAlertIcon.setVisibility(View.GONE);
};
@@ -336,25 +354,30 @@ public class NoteEditActivity extends Activity implements OnClickListener,
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
+ // 如果笔记背景颜色选择器可见,并且触摸事件不在笔记背景颜色选择器范围内,则隐藏笔记背景颜色选择器并返回true。
if (mNoteBgColorSelector.getVisibility() == View.VISIBLE
&& !inRangeOfView(mNoteBgColorSelector, ev)) {
mNoteBgColorSelector.setVisibility(View.GONE);
return true;
}
+ // 如果字体大小选择器可见,并且触摸事件不在字体大小选择器范围内,则隐藏字体大小选择器并返回true。
if (mFontSizeSelector.getVisibility() == View.VISIBLE
&& !inRangeOfView(mFontSizeSelector, ev)) {
mFontSizeSelector.setVisibility(View.GONE);
return true;
}
+ // 返回父类的dispatchTouchEvent方法。
return super.dispatchTouchEvent(ev);
}
private boolean inRangeOfView(View view, MotionEvent ev) {
+ // 获取视图在屏幕上的位置。
int []location = new int[2];
view.getLocationOnScreen(location);
int x = location[0];
int y = location[1];
+ // 如果触摸事件的x坐标小于视图的x坐标、大于视图的宽度和x坐标之和、y坐标小于视图的y坐标、或大于视图的高度和y坐标之和,则返回false,否则返回true。
if (ev.getX() < x
|| ev.getX() > (x + view.getWidth())
|| ev.getY() < y
@@ -405,7 +428,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
Log.d(TAG, "Note data was saved with length:" + mWorkingNote.getContent().length());
}
clearSettingState();
- }
+ }//onPause()方法在活动即将暂停时被调用。如果有任何更改,它会保存当前笔记,并清除任何设置状态。
private void updateWidget() {
Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
@@ -413,10 +436,8 @@ public class NoteEditActivity extends Activity implements OnClickListener,
intent.setClass(this, NoteWidgetProvider_2x.class);
} else if (mWorkingNote.getWidgetType() == Notes.TYPE_WIDGET_4X) {
intent.setClass(this, NoteWidgetProvider_4x.class);
- } else if (mWorkingNote.getWidgetType() == Notes.TYPE_WIDGET_3X) {
- intent.setClass(this, NoteWidgetProvider_3x.class);
} else {
- Log.e(TAG, "Unsupported widget type");
+ Log.e(TAG, "Unspported widget type");
return;
}
@@ -426,14 +447,16 @@ public class NoteEditActivity extends Activity implements OnClickListener,
sendBroadcast(intent);
setResult(RESULT_OK, intent);
- }
+ }//updateWidget()方法更新与当前笔记相关联的小部件。它创建一个意图,并根据笔记的小部件类型设置相应的小部件提供程序类。然后它发送一个广播,带有小部件ID以更新小部件。
+
+
public void onClick(View v) {
int id = v.getId();
if (id == R.id.btn_set_bg_color) {
mNoteBgColorSelector.setVisibility(View.VISIBLE);
findViewById(sBgSelectorSelectionMap.get(mWorkingNote.getBgColorId())).setVisibility(
- View.VISIBLE);
+ - View.VISIBLE);
} else if (sBgSelectorBtnsMap.containsKey(id)) {
findViewById(sBgSelectorSelectionMap.get(mWorkingNote.getBgColorId())).setVisibility(
View.GONE);
@@ -453,7 +476,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}
mFontSizeSelector.setVisibility(View.GONE);
}
- }
+ }//onClick()方法处理UI中各种按钮的点击事件。当单击相应的按钮时,它会显示颜色选择器或字体大小选择器。它还根据所选选项更新笔记的字体大小或背景颜色。
@Override
public void onBackPressed() {
@@ -463,7 +486,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
saveNote();
super.onBackPressed();
- }
+ }//onBackPressed()方法在按下返回按钮时被调用。它检查当前是否有任何设置状态处于活动状态,并清除它。然后它保存当前笔记并调用超类实现。
private boolean clearSettingState() {
if (mNoteBgColorSelector.getVisibility() == View.VISIBLE) {
@@ -474,14 +497,14 @@ public class NoteEditActivity extends Activity implements OnClickListener,
return true;
}
return false;
- }
+ }//clearSettingState()方法检查当前是否有任何设置状态处于活动状态,并清除它。
public void onBackgroundColorChanged() {
findViewById(sBgSelectorSelectionMap.get(mWorkingNote.getBgColorId())).setVisibility(
View.VISIBLE);
mNoteEditorPanel.setBackgroundResource(mWorkingNote.getBgColorResId());
mHeadViewPanel.setBackgroundResource(mWorkingNote.getTitleBgResId());
- }
+ }//onBackgroundColorChanged()方法在选择新的背景颜色时被调用。它更新笔记的背景颜色,并更新颜色选择器的颜色。
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
@@ -506,7 +529,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
menu.findItem(R.id.menu_delete_remind).setVisible(false);
}
return true;
- }
+ }//onFontSizeChanged()方法在选择新的字体大小时被调用。它更新笔记的字体大小,并更新字体大小选择器的值。
@Override
public boolean onOptionsItemSelected(MenuItem item) {
@@ -575,7 +598,8 @@ public class NoteEditActivity extends Activity implements OnClickListener,
intent.putExtra(Intent.EXTRA_TEXT, info);
intent.setType("text/plain");
context.startActivity(intent);
- }
+ }//sendTo(Context context, String info)方法创建一个新的意图,并使用Intent.EXTRA_TEXT将信息作为文本传递。它的目的是启动共享对话框,让用户分享笔记的内容。
+
private void createNewNote() {
// Firstly, save current editing notes
@@ -587,7 +611,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
intent.setAction(Intent.ACTION_INSERT_OR_EDIT);
intent.putExtra(Notes.INTENT_EXTRA_FOLDER_ID, mWorkingNote.getFolderId());
startActivity(intent);
- }
+ }//createNewNote()方法保存当前正在编辑的笔记,然后启动一个新的NoteEditActivity以创建一个新的笔记。通过设置Intent.ACTION_INSERT_OR_EDIT和Notes.INTENT_EXTRA_FOLDER_ID,该方法指示NoteEditActivity启动以插入或编辑笔记,并指定所选文件夹的ID。
private void deleteCurrentNote() {
if (mWorkingNote.existInDatabase()) {
@@ -609,11 +633,11 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}
}
mWorkingNote.markDeleted(true);
- }
+ }//deleteCurrentNote()方法删除当前笔记。如果该笔记已存储在数据库中,则将其从数据库中删除。如果应用程序处于同步模式下,则将其移动到垃圾文件夹中,而不是永久删除。无论是删除还是移动,该方法都会将当前笔记标记为已删除。
private boolean isSyncMode() {
return NotesPreferenceActivity.getSyncAccountName(this).trim().length() > 0;
- }
+ }//isSyncMode()方法检查应用程序是否处于同步模式。如果已经选择了同步帐户,则返回true。否则,返回false。
public void onClockAlertChanged(long date, boolean set) {
/**
@@ -648,6 +672,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
public void onWidgetChanged() {
updateWidget();
}
+// onWidgetChanged()方法会在小部件更改时被调用。它会调用updateWidget()方法来更新小部件。
public void onEditTextDelete(int index, String text) {
int childCount = mEditTextList.getChildCount();
@@ -674,6 +699,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
edit.requestFocus();
edit.setSelection(length);
}
+// onEditTextDelete(int index, String text)方法会在删除NoteEditText视图时被调用。该方法首先检查是否只有一个NoteEditText视图存在,如果是则直接返回。然后,该方法会将所有后续视图的索引递减1。接下来,该方法会删除指定索引处的NoteEditText视图,并将其文本追加到前一个视图的文本中,以便将文本合并到一个视图中。最后,该方法将焦点设置在前一个视图中,并将光标移动到文本末尾。
public void onEditTextEnter(int index, String text) {
/**
@@ -710,6 +736,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
mNoteEditor.setVisibility(View.GONE);
mEditTextList.setVisibility(View.VISIBLE);
}
+// switchToListMode(String text)方法用于切换到清单模式。该方法首先清除所有视图,然后将文本根据换行符分隔为多个条目,并将每个条目添加到mEditTextList中。同时,该方法会添加一个新的空条目,以便用户可以在列表末尾添加新的条目。最后,该方法会将焦点设置在最后一个条目上,并将编辑器视图隐藏,将列表视图显示。
private Spannable getHighlightQueryResult(String fullText, String userQuery) {
SpannableString spannable = new SpannableString(fullText == null ? "" : fullText);
@@ -727,6 +754,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}
return spannable;
}
+// getHighlightQueryResult(String fullText, String userQuery)方法用于标记在搜索查询中匹配的文本。该方法将返回一个Spannable对象,其中查询匹配的文本会被高亮显示。
private View getListItem(String item, int index) {
View view = LayoutInflater.from(this).inflate(R.layout.note_edit_list_item, null);
@@ -758,6 +786,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
edit.setText(getHighlightQueryResult(item, mUserQuery));
return view;
}
+// getListItem(String item, int index)方法用于获取一个清单视图。该方法将从R.layout.note_edit_list_item文件中充气视图。在充气视图之后,该方法会将文本添加到NoteEditText视图中,并将复选框设置为选中或未选中状态。如果条目已选中,则文本将具有删除线。最后,该方法将返回该视图。
public void onTextChange(int index, boolean hasText) {
if (index >= mEditTextList.getChildCount()) {
@@ -770,6 +799,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
mEditTextList.getChildAt(index).findViewById(R.id.cb_edit_item).setVisibility(View.GONE);
}
}
+// onTextChange(int index, boolean hasText)方法用于在清单视图中标记是否有文本。如果hasText为true,则将显示复选框;否则,将隐藏复选框。
public void onCheckListModeChanged(int oldMode, int newMode) {
if (newMode == TextNote.MODE_CHECK_LIST) {
@@ -784,6 +814,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
mNoteEditor.setVisibility(View.VISIBLE);
}
}
+// onCheckListModeChanged(int oldMode, int newMode)方法用于在清单模式和文本编辑模式之间切换。如果新模式为清单模式,则将文本转换为清单视图;否则,将清单视图转换为文本编辑视图。
private boolean getWorkingText() {
boolean hasChecked = false;
@@ -807,6 +838,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}
return hasChecked;
}
+// getWorkingText()方法用于获取当前工作文本。如果当前模式为清单模式,则将所有条目合并为一个字符串,并添加检查框状态。否则,将返回当前编辑器文本。
private boolean saveNote() {
getWorkingText();
diff --git a/src/Notes/app/src/main/java/net/micode/notes/ui/NoteEditText.java b/src/Notes/app/src/main/java/net/micode/notes/ui/NoteEditText.java
index 2afe2a8..a4179e7 100644
--- a/src/Notes/app/src/main/java/net/micode/notes/ui/NoteEditText.java
+++ b/src/Notes/app/src/main/java/net/micode/notes/ui/NoteEditText.java
@@ -84,11 +84,11 @@ public class NoteEditText extends EditText {
public void setIndex(int index) {
mIndex = index;
- }
+ }//用于设置控件在父容器中的位置索引
public void setOnTextViewChangeListener(OnTextViewChangeListener listener) {
mOnTextViewChangeListener = listener;
- }
+ }//用于设置文本变化的监听器
public NoteEditText(Context context, AttributeSet attrs) {
super(context, attrs, android.R.attr.editTextStyle);
@@ -116,7 +116,7 @@ public class NoteEditText extends EditText {
int off = layout.getOffsetForHorizontal(line, x);
Selection.setSelection(getText(), off);
break;
- }
+ }//实现了点击控件后,将光标移动到点击位置的功能
return super.onTouchEvent(event);
}
@@ -166,6 +166,7 @@ public class NoteEditText extends EditText {
}
return super.onKeyUp(keyCode, event);
}
+// onKeyDown和onKeyUp方法实现了按下和松开键盘按键时的响应。
@Override
protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
@@ -177,7 +178,7 @@ public class NoteEditText extends EditText {
}
}
super.onFocusChanged(focused, direction, previouslyFocusedRect);
- }
+ }//控件获得或失去焦点时触发,将焦点状态通知给监听器。
@Override
protected void onCreateContextMenu(ContextMenu menu) {
@@ -214,4 +215,5 @@ public class NoteEditText extends EditText {
}
super.onCreateContextMenu(menu);
}
+// 创建上下文菜单,当用户长按控件中的链接时,根据链接的协议类型创建不同的菜单项,点击菜单项后跳转到相应的链接。
}
diff --git a/src/Notes/app/src/main/java/net/micode/notes/ui/NotesListActivity.java b/src/Notes/app/src/main/java/net/micode/notes/ui/NotesListActivity.java
index c00449e..4d980ad 100644
--- a/src/Notes/app/src/main/java/net/micode/notes/ui/NotesListActivity.java
+++ b/src/Notes/app/src/main/java/net/micode/notes/ui/NotesListActivity.java
@@ -70,7 +70,6 @@ import net.micode.notes.tool.DataUtils;
import net.micode.notes.tool.ResourceParser;
import net.micode.notes.ui.NotesListAdapter.AppWidgetAttribute;
import net.micode.notes.widget.NoteWidgetProvider_2x;
-import net.micode.notes.widget.NoteWidgetProvider_3x;
import net.micode.notes.widget.NoteWidgetProvider_4x;
import java.io.BufferedReader;
@@ -142,7 +141,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
setContentView(R.layout.note_list);
initResources();
- /*
+ /**
* Insert an introduction when user firstly use this application
*/
setAppInfoFromRawRes();
@@ -157,10 +156,12 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
super.onActivityResult(requestCode, resultCode, data);
}
}
+// 这个方法重写了Activity类的onActivityResult()方法。当startActivityForResult()启动的活动结束时,它会被调用。它检查结果是否为RESULT_OK并且请求了REQUEST_CODE_OPEN_NODE或REQUEST_CODE_NEW_NODE。如果是,则通过调用changeCursor(null)更新笔记列表适配器。否则,它调用超类实现的onActivityResult()方法。
private void setAppInfoFromRawRes() {
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
if (!sp.getBoolean(PREFERENCE_ADD_INTRODUCTION, false)) {
+ // 从raw资源中读取介绍文件
StringBuilder sb = new StringBuilder();
InputStream in = null;
try {
@@ -203,6 +204,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
}
}
}
+// 这个方法从一个原始的资源文件中读取介绍文件,并将其内容添加到应用程序的SharedPreferences中。如果介绍文件尚未被添加到SharedPreferences中,它将被添加,并设置一个标志表示文件已被添加。在此之后,每次启动应用程序时,它将不再读取介绍文件。
@Override
protected void onStart() {
@@ -269,6 +271,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
});
return true;
}
+// 这是Activity的onCreate()方法,它在创建活动时被调用。它设置了视图并调用了setAppInfoFromRawRes()和initNoteListView()方法以初始化应用程序。
private void updateMenu() {
int selectedCount = mNotesListAdapter.getSelectedCount();
@@ -285,33 +288,33 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
item.setTitle(R.string.menu_select_all);
}
}
- }
+ }//更新下拉菜单中的选项。该方法首先获取当前选中的笔记数量,然后格式化菜单标题,更新下拉菜单的标题,并更新菜单项的状态。
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
// TODO Auto-generated method stub
return false;
- }
+ }//准备操作模式。该方法在操作模式即将被启动时调用,并返回一个布尔值,指示是否应该启动操作模式。
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
// TODO Auto-generated method stub
return false;
- }
+ }//处理操作模式中的菜单项点击事件。该方法在用户点击操作模式中的菜单项时调用,并返回一个布尔值,指示是否已经处理了该事件。
public void onDestroyActionMode(ActionMode mode) {
mNotesListAdapter.setChoiceMode(false);
mNotesListView.setLongClickable(true);
mAddNewNote.setVisibility(View.VISIBLE);
- }
+ }//销毁操作模式。该方法在操作模式被销毁时调用,并将列表适配器的选择模式设置为false,将列表项的长按功能重新启用,并显示添加新笔记的按钮。
public void finishActionMode() {
mActionMode.finish();
- }
+ }//结束操作模式。该方法结束操作模式。
public void onItemCheckedStateChanged(ActionMode mode, int position, long id,
boolean checked) {
mNotesListAdapter.setCheckedItem(position, checked);
updateMenu();
- }
+ }//当用户选中或取消选中一个列表项时调用。该方法更新适配器中对应列表项的选中状态,并调用updateMenu()方法更新下拉菜单中的选项。
public boolean onMenuItemClick(MenuItem item) {
if (mNotesListAdapter.getSelectedCount() == 0) {
@@ -345,6 +348,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
}
return true;
}
+// 处理下拉菜单中的菜单项点击事件。该方法在用户点击下拉菜单中的菜单项时调用,并根据菜单项的ID执行相应的操作。如果成功处理了菜单项,则返回true,否则返回false。如果没有选中任何笔记,则显示一个Toast提示用户需要先选择笔记。如果选择了“删除”菜单项,则弹出一个对话框,询问用户是否确定要删除所选笔记。如果选择了“移动”菜单项,则启动查询目标文件夹的操作。
}
private class NewNoteOnTouchListener implements OnTouchListener {
@@ -418,21 +422,27 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
}, NoteColumns.TYPE + " DESC," + NoteColumns.MODIFIED_DATE + " DESC");
}
+// 后台查询处理程序,继承自AsyncQueryHandler
private final class BackgroundQueryHandler extends AsyncQueryHandler {
public BackgroundQueryHandler(ContentResolver contentResolver) {
super(contentResolver);
}
+// 构造函数,调用父类AsyncQueryHandler的构造函数
+ // 查询完成后的回调函数,根据token值进行不同的处理
@Override
protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
switch (token) {
case FOLDER_NOTE_LIST_QUERY_TOKEN:
+ // 更新列表Adapter的Cursor
mNotesListAdapter.changeCursor(cursor);
break;
case FOLDER_LIST_QUERY_TOKEN:
if (cursor != null && cursor.getCount() > 0) {
+ // 显示文件夹列表菜单
showFolderListMenu(cursor);
} else {
+ // 查询文件夹失败,输出错误信息
Log.e(TAG, "Query folder failed");
}
break;
@@ -442,35 +452,48 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
}
}
+ // 显示文件夹列表菜单
private void showFolderListMenu(Cursor cursor) {
+ // 创建AlertDialog.Builder
AlertDialog.Builder builder = new AlertDialog.Builder(NotesListActivity.this);
builder.setTitle(R.string.menu_title_select_folder);
+ // 创建文件夹列表的Adapter
final FoldersListAdapter adapter = new FoldersListAdapter(this, cursor);
+ // 设置Adapter和点击事件
builder.setAdapter(adapter, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
+ // 批量移动选中的笔记到指定文件夹
DataUtils.batchMoveToFolder(mContentResolver,
mNotesListAdapter.getSelectedItemIds(), adapter.getItemId(which));
+ // 显示移动笔记的提示信息
Toast.makeText(
NotesListActivity.this,
getString(R.string.format_move_notes_to_folder,
mNotesListAdapter.getSelectedCount(),
adapter.getFolderName(NotesListActivity.this, which)),
Toast.LENGTH_SHORT).show();
+ // 结束ActionMode
mModeCallBack.finishActionMode();
}
});
+ // 显示AlertDialog
builder.show();
}
+ // 创建新笔记
private void createNewNote() {
+ // 创建Intent,跳转到NoteEditActivity
Intent intent = new Intent(this, NoteEditActivity.class);
intent.setAction(Intent.ACTION_INSERT_OR_EDIT);
intent.putExtra(Notes.INTENT_EXTRA_FOLDER_ID, mCurrentFolderId);
+ // 启动ActivityForResult
this.startActivityForResult(intent, REQUEST_CODE_NEW_NODE);
}
+ // 批量删除选中的笔记
private void batchDelete() {
+ // 创建异步任务
new AsyncTask>() {
protected HashSet doInBackground(Void... unused) {
HashSet widgets = mNotesListAdapter.getSelectedWidget();
@@ -534,47 +557,52 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
}
}
+ // 打开笔记详情页
private void openNode(NoteItemData data) {
Intent intent = new Intent(this, NoteEditActivity.class);
intent.setAction(Intent.ACTION_VIEW);
- intent.putExtra(Intent.EXTRA_UID, data.getId());
- this.startActivityForResult(intent, REQUEST_CODE_OPEN_NODE);
+ intent.putExtra(Intent.EXTRA_UID, data.getId());// 将笔记的id作为参数传递给NoteEditActivity
+ this.startActivityForResult(intent, REQUEST_CODE_OPEN_NODE);// 启动NoteEditActivity,并等待返回结果
}
+ // 打开文件夹
private void openFolder(NoteItemData data) {
- mCurrentFolderId = data.getId();
- startAsyncNotesListQuery();
- if (data.getId() == Notes.ID_CALL_RECORD_FOLDER) {
- mState = ListEditState.CALL_RECORD_FOLDER;
- mAddNewNote.setVisibility(View.GONE);
+ mCurrentFolderId = data.getId();// 将当前文件夹的id保存到成员变量mCurrentFolderId
+ startAsyncNotesListQuery();// 异步查询当前文件夹下的笔记列表
+ if (data.getId() == Notes.ID_CALL_RECORD_FOLDER) {// 如果打开的是CallRecord文件夹
+ mState = ListEditState.CALL_RECORD_FOLDER;// 设置状态为CALL_RECORD_FOLDER
+ mAddNewNote.setVisibility(View.GONE);// 隐藏新建笔记按钮
} else {
- mState = ListEditState.SUB_FOLDER;
+ mState = ListEditState.SUB_FOLDER;// 设置状态为SUB_FOLDER
}
- if (data.getId() == Notes.ID_CALL_RECORD_FOLDER) {
- mTitleBar.setText(R.string.call_record_folder_name);
+ if (data.getId() == Notes.ID_CALL_RECORD_FOLDER) {// 如果打开的是CallRecord文件夹
+ mTitleBar.setText(R.string.call_record_folder_name);// 将标题栏文本设置为"通话录音"
} else {
- mTitleBar.setText(data.getSnippet());
+ mTitleBar.setText(data.getSnippet());// 将标题栏文本设置为当前文件夹的名字
}
- mTitleBar.setVisibility(View.VISIBLE);
+ mTitleBar.setVisibility(View.VISIBLE); // 显示标题栏
}
+ // 按钮点击事件
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_new_note:
- createNewNote();
+ createNewNote();// 创建新笔记
break;
default:
break;
}
}
+ // 显示软键盘
private void showSoftInput() {
InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
if (inputMethodManager != null) {
- inputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
+ inputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); // 显示软键盘
}
}
+ // 隐藏软键盘
private void hideSoftInput(View view) {
InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0);
@@ -663,7 +691,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
}
});
- }
+ }//用于显示一个对话框,让用户输入或修改一个文件夹的名称。
@Override
public void onBackPressed() {
@@ -688,6 +716,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
break;
}
}
+// 重写返回键的行为,根据当前的状态执行不同的操作,如返回到上一级文件夹、返回到笔记列表、或者直接退出应用程序。
private void updateWidget(int appWidgetId, int appWidgetType) {
Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
@@ -695,8 +724,6 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
intent.setClass(this, NoteWidgetProvider_2x.class);
} else if (appWidgetType == Notes.TYPE_WIDGET_4X) {
intent.setClass(this, NoteWidgetProvider_4x.class);
- } else if (appWidgetType == Notes.TYPE_WIDGET_3X) {
- intent.setClass(this, NoteWidgetProvider_3x.class);
} else {
Log.e(TAG, "Unspported widget type");
return;
@@ -709,6 +736,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
sendBroadcast(intent);
setResult(RESULT_OK, intent);
}
+// 更新小部件的方法,根据小部件的类型选择不同的小部件提供者,并发送广播更新小部件。
private final OnCreateContextMenuListener mFolderOnCreateContextMenuListener = new OnCreateContextMenuListener() {
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
@@ -720,6 +748,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
}
}
};
+// 长按文件夹时创建上下文菜单的监听器,菜单包括查看文件夹、删除文件夹和修改文件夹名称等选项。
@Override
public void onContextMenuClosed(Menu menu) {
@@ -728,6 +757,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
}
super.onContextMenuClosed(menu);
}
+// 上下文菜单关闭时的操作,将监听器设为null。
@Override
public boolean onContextItemSelected(MenuItem item) {
@@ -762,6 +792,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
return true;
}
+// 选择上下文菜单选项时的操作,根据所选选项执行不同的操作,如打开文件夹、删除文件夹或修改文件夹名称。
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
@@ -780,6 +811,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
}
return true;
}
+// 准备选项菜单时的操作,根据当前的状态显示不同的菜单选项,如笔记列表、子文件夹或通话记录文件夹。
@Override
public boolean onOptionsItemSelected(MenuItem item) {
@@ -820,6 +852,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
}
return true;
}
+// 选择选项菜单选项时的操作,根据所选选项执行不同的操作,如打开笔记列表、打开子文件夹或打开通话记录文件夹。
@Override
public boolean onSearchRequested() {
@@ -872,12 +905,14 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
private boolean isSyncMode() {
return NotesPreferenceActivity.getSyncAccountName(this).trim().length() > 0;
}
+// ,表示当前是否处于同步模式。它通过调用 NotesPreferenceActivity.getSyncAccountName(this) 获取同步账户名,并检查它的长度是否大于 0 来确定是否启用同步模式。
private void startPreferenceActivity() {
Activity from = getParent() != null ? getParent() : this;
Intent intent = new Intent(from, NotesPreferenceActivity.class);
from.startActivityIfNeeded(intent, -1);
}
+// 方法启动设置活动,它创建一个 Intent 对象并使用当前活动作为上下文调用 startActivityIfNeeded() 方法来启动设置活动。如果当前活动已经是设置活动的父级,则使用 getParent() 方法获取父级活动。
private class OnListItemClickListener implements OnItemClickListener {
@@ -919,6 +954,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
}
}
+// OnListItemClickListener 是一个内部类,实现了 OnItemClickListener 接口。它覆盖了 onItemClick() 方法,在列表项被单击时执行一系列操作。首先,它检查当前是否处于选择模式。如果是,则根据列表项的类型执行不同的操作。如果不是,则根据当前状态执行不同的操作,如打开文件夹或笔记。
private void startQueryDestinationFolders() {
String selection = NoteColumns.TYPE + "=? AND " + NoteColumns.PARENT_ID + "<>? AND " + NoteColumns.ID + "<>?";
@@ -937,6 +973,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
},
NoteColumns.MODIFIED_DATE + " DESC");
}
+// 启动后台查询,以获取目标文件夹列表。它构建一个查询选择器,通过调用 mBackgroundQueryHandler.startQuery() 方法执行查询操作。查询的结果将被传递到 FoldersListAdapter 中进行处理。
public boolean onItemLongClick(AdapterView> parent, View view, int position, long id) {
if (view instanceof NotesListItem) {
@@ -954,4 +991,5 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
}
return false;
}
+// 在列表项被长按时执行。它首先获取当前长按的列表项,并将其类型存储在 mFocusNoteDataItem 中。如果类型为笔记且不在选择模式下,则启动上下文操作模式,并将当前列表项标记为已选中。如果类型为文件夹,则设置上下文菜单的创建监听器。
}
diff --git a/src/Notes/app/src/main/java/net/micode/notes/ui/NotesListAdapter.java b/src/Notes/app/src/main/java/net/micode/notes/ui/NotesListAdapter.java
index 51c9cb9..18f72ef 100644
--- a/src/Notes/app/src/main/java/net/micode/notes/ui/NotesListAdapter.java
+++ b/src/Notes/app/src/main/java/net/micode/notes/ui/NotesListAdapter.java
@@ -53,7 +53,7 @@ public class NotesListAdapter extends CursorAdapter {
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return new NotesListItem(context);
- }
+ }//创建一个新的笔记列表项视图,即 NotesListItem。
@Override
public void bindView(View view, Context context, Cursor cursor) {
@@ -62,21 +62,21 @@ public class NotesListAdapter extends CursorAdapter {
((NotesListItem) view).bind(context, itemData, mChoiceMode,
isSelectedItem(cursor.getPosition()));
}
- }
+ }//将笔记数据绑定到给定的笔记列表项视图中。
public void setCheckedItem(final int position, final boolean checked) {
mSelectedIndex.put(position, checked);
notifyDataSetChanged();
- }
+ }//设置给定位置的笔记是否被选中,并通知适配器数据已更改。
public boolean isInChoiceMode() {
return mChoiceMode;
- }
+ }//返回是否处于选择笔记的模式。
public void setChoiceMode(boolean mode) {
mSelectedIndex.clear();
mChoiceMode = mode;
- }
+ }//设置选择笔记的模式,并清空 mSelectedIndex。
public void selectAll(boolean checked) {
Cursor cursor = getCursor();
@@ -87,7 +87,7 @@ public class NotesListAdapter extends CursorAdapter {
}
}
}
- }
+ }//选择所有笔记。
public HashSet getSelectedItemIds() {
HashSet itemSet = new HashSet();
@@ -103,7 +103,8 @@ public class NotesListAdapter extends CursorAdapter {
}
return itemSet;
- }
+ }//返回选定的笔记的 ID。
+
public HashSet getSelectedWidget() {
HashSet itemSet = new HashSet();
@@ -126,7 +127,7 @@ public class NotesListAdapter extends CursorAdapter {
}
}
return itemSet;
- }
+ }//返回选定的小部件信息。
public int getSelectedCount() {
Collection values = mSelectedIndex.values();
@@ -141,31 +142,31 @@ public class NotesListAdapter extends CursorAdapter {
}
}
return count;
- }
+ }//返回选定笔记的数量。
public boolean isAllSelected() {
int checkedCount = getSelectedCount();
return (checkedCount != 0 && checkedCount == mNotesCount);
- }
+ }//返回是否已经选择了所有笔记。
public boolean isSelectedItem(final int position) {
if (null == mSelectedIndex.get(position)) {
return false;
}
return mSelectedIndex.get(position);
- }
+ }//返回给定位置的笔记是否被选中。
@Override
protected void onContentChanged() {
super.onContentChanged();
calcNotesCount();
- }
+ }//当笔记数据发生变化时,重新计算笔记数量。
@Override
public void changeCursor(Cursor cursor) {
super.changeCursor(cursor);
calcNotesCount();
- }
+ }//更改笔记数据游标时,重新计算笔记数量。
private void calcNotesCount() {
mNotesCount = 0;
@@ -180,5 +181,5 @@ public class NotesListAdapter extends CursorAdapter {
return;
}
}
- }
+ }//计算笔记数量。
}
diff --git a/src/Notes/app/src/main/java/net/micode/notes/ui/NotesListItem.java b/src/Notes/app/src/main/java/net/micode/notes/ui/NotesListItem.java
index 1221e80..147c4ea 100644
--- a/src/Notes/app/src/main/java/net/micode/notes/ui/NotesListItem.java
+++ b/src/Notes/app/src/main/java/net/micode/notes/ui/NotesListItem.java
@@ -98,6 +98,7 @@ public class NotesListItem extends LinearLayout {
setBackground(data);
}
+ // 用于将数据绑定到视图的UI组件上,它接受一个NoteItemData对象,其中包含有关笔记项的信息,以及两个布尔标志:choiceMode和checked。
private void setBackground(NoteItemData data) {
int id = data.getBgColorId();
diff --git a/src/Notes/app/src/main/java/net/micode/notes/ui/NotesPreferenceActivity.java b/src/Notes/app/src/main/java/net/micode/notes/ui/NotesPreferenceActivity.java
index 07c5f7e..ed4d6af 100644
--- a/src/Notes/app/src/main/java/net/micode/notes/ui/NotesPreferenceActivity.java
+++ b/src/Notes/app/src/main/java/net/micode/notes/ui/NotesPreferenceActivity.java
@@ -86,7 +86,7 @@ public class NotesPreferenceActivity extends PreferenceActivity {
mOriAccounts = null;
View header = LayoutInflater.from(this).inflate(R.layout.settings_header, null);
getListView().addHeaderView(header, null, true);
- }
+ }//当创建Activity时调用。在此方法中,ActionBar的返回按钮启用,加载应用程序的偏好设置,注册广播接收器,添加一个标题视图。
@Override
protected void onResume() {
@@ -114,7 +114,7 @@ public class NotesPreferenceActivity extends PreferenceActivity {
}
refreshUI();
- }
+ }//当Activity从暂停状态恢复时调用。在此方法中,检查用户是否已添加了新帐户,如果是,则需要自动设置同步帐户。
@Override
protected void onDestroy() {
@@ -122,7 +122,7 @@ public class NotesPreferenceActivity extends PreferenceActivity {
unregisterReceiver(mReceiver);
}
super.onDestroy();
- }
+ }//当Activity被销毁时调用。在此方法中,注销广播接收器。
private void loadAccountPreference() {
mAccountCategory.removeAll();
@@ -152,7 +152,7 @@ public class NotesPreferenceActivity extends PreferenceActivity {
});
mAccountCategory.addPreference(accountPref);
- }
+ }//加载应用程序的帐户偏好设置,包括标题、摘要和单击事件监听器。
private void loadSyncButton() {
Button syncButton = (Button) findViewById(R.id.preference_sync_button);
@@ -191,12 +191,12 @@ public class NotesPreferenceActivity extends PreferenceActivity {
lastSyncTimeView.setVisibility(View.GONE);
}
}
- }
+ }//加载同步按钮和上次同步时间文本视图,并设置相应的单击事件监听器。
private void refreshUI() {
loadAccountPreference();
loadSyncButton();
- }
+ }//刷新用户界面,加载帐户偏好设置和同步按钮。
private void showSelectAccountAlertDialog() {
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
@@ -252,7 +252,7 @@ public class NotesPreferenceActivity extends PreferenceActivity {
dialog.dismiss();
}
});
- }
+ }//弹出一个对话框,提示用户选择一个帐户进行同步。
private void showChangeAccountConfirmAlertDialog() {
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
@@ -384,5 +384,5 @@ public class NotesPreferenceActivity extends PreferenceActivity {
default:
return false;
}
- }
+ }//当用户选择同步帐户时调用。在此方法中,更新同步按钮的文本视图,并启用同步按钮。
}
From c7a7013c76a187b735c778eb2fecf591638aa311 Mon Sep 17 00:00:00 2001
From: gexinghai <2874903098@qq.com>
Date: Tue, 25 Apr 2023 22:49:31 +0800
Subject: [PATCH 6/7] =?UTF-8?q?=E6=8F=90=E4=BA=A4?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../buildOutputCleanup.lock | Bin 17 -> 17 bytes
.../buildOutputCleanup/cache.properties | 4 ++--
.../buildOutputCleanup/outputFiles.bin | Bin 21143 -> 21251 bytes
src/Notes/.gradle/file-system.probe | Bin 8 -> 8 bytes
src/Notes/app/build.gradle | 1 +
src/Notes/app/src/main/AndroidManifest.xml | 1 -
.../net/micode/notes/ui/NoteEditActivity.java | 4 ++--
src/Notes/build.gradle | 2 +-
src/Notes/gradle.properties | 3 +++
.../gradle/wrapper/gradle-wrapper.properties | 2 +-
10 files changed, 10 insertions(+), 7 deletions(-)
create mode 100644 src/Notes/gradle.properties
diff --git a/src/Notes/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/src/Notes/.gradle/buildOutputCleanup/buildOutputCleanup.lock
index 954fdfe768077d02bbc42cc917898e521aad2ca1..927f3d8a84bfade90e1cdd9e4c8f429ec154ad09 100644
GIT binary patch
literal 17
VcmZRcBz45$;=iS#3}C>t6aY7{1tb6f
literal 17
VcmZRcBz45$;=iS#3}C?c0RT7o1#SQU
diff --git a/src/Notes/.gradle/buildOutputCleanup/cache.properties b/src/Notes/.gradle/buildOutputCleanup/cache.properties
index 299c01e..0eba958 100644
--- a/src/Notes/.gradle/buildOutputCleanup/cache.properties
+++ b/src/Notes/.gradle/buildOutputCleanup/cache.properties
@@ -1,2 +1,2 @@
-#Sun Apr 02 08:57:27 CST 2023
-gradle.version=7.5
+#Sun Apr 23 18:04:59 CST 2023
+gradle.version=8.0
diff --git a/src/Notes/.gradle/buildOutputCleanup/outputFiles.bin b/src/Notes/.gradle/buildOutputCleanup/outputFiles.bin
index 1d2c5943108ac22b6a3999f9d0ad9c43bc29e48c..5e353d5402f6ac4f3c0a512adc9cb5afa6161d80 100644
GIT binary patch
literal 21251
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
M%Dhd_|6*VN0Czat1ONa4
literal 21143
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
diff --git a/src/Notes/.gradle/file-system.probe b/src/Notes/.gradle/file-system.probe
index efea4229efb376ab89875ee2c5f669481776bd07..9cc85cefe894f155380edfff9b93f4f3aeb377e1 100644
GIT binary patch
literal 8
PcmZQzU~FGIW&cC~2`~d1
literal 8
PcmZQzU~FGhz_beh2S)-|
diff --git a/src/Notes/app/build.gradle b/src/Notes/app/build.gradle
index ae0b4c4..1e45ad2 100644
--- a/src/Notes/app/build.gradle
+++ b/src/Notes/app/build.gradle
@@ -17,4 +17,5 @@ android {
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
+ namespace 'net.micode.notes'
}
diff --git a/src/Notes/app/src/main/AndroidManifest.xml b/src/Notes/app/src/main/AndroidManifest.xml
index 41511bc..a30799f 100644
--- a/src/Notes/app/src/main/AndroidManifest.xml
+++ b/src/Notes/app/src/main/AndroidManifest.xml
@@ -17,7 +17,6 @@
diff --git a/src/Notes/app/src/main/java/net/micode/notes/ui/NoteEditActivity.java b/src/Notes/app/src/main/java/net/micode/notes/ui/NoteEditActivity.java
index 387c03a..9cfb996 100644
--- a/src/Notes/app/src/main/java/net/micode/notes/ui/NoteEditActivity.java
+++ b/src/Notes/app/src/main/java/net/micode/notes/ui/NoteEditActivity.java
@@ -322,7 +322,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
- /**
+ /*
* For new note without note id, we should firstly save it to
* generate a id. If the editing note is not worth saving, there
* is no id which is equivalent to create new note
@@ -387,7 +387,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
};
mSharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
mFontSizeId = mSharedPrefs.getInt(PREFERENCE_FONT_SIZE, ResourceParser.BG_DEFAULT_FONT_SIZE);
- /**
+ /*
* HACKME: Fix bug of store the resource id in shared preference.
* The id may larger than the length of resources, in this case,
* return the {@link ResourceParser#BG_DEFAULT_FONT_SIZE}
diff --git a/src/Notes/build.gradle b/src/Notes/build.gradle
index cdb59e3..07f17b1 100644
--- a/src/Notes/build.gradle
+++ b/src/Notes/build.gradle
@@ -5,7 +5,7 @@ buildscript {
jcenter()
}
dependencies {
- classpath 'com.android.tools.build:gradle:7.4.2'
+ classpath 'com.android.tools.build:gradle:8.0.0'
}
}
diff --git a/src/Notes/gradle.properties b/src/Notes/gradle.properties
new file mode 100644
index 0000000..f82049a
--- /dev/null
+++ b/src/Notes/gradle.properties
@@ -0,0 +1,3 @@
+android.defaults.buildfeatures.buildconfig=true
+android.nonFinalResIds=false
+android.nonTransitiveRClass=false
\ No newline at end of file
diff --git a/src/Notes/gradle/wrapper/gradle-wrapper.properties b/src/Notes/gradle/wrapper/gradle-wrapper.properties
index 829fbb8..ff44dd1 100644
--- a/src/Notes/gradle/wrapper/gradle-wrapper.properties
+++ b/src/Notes/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
#Sun Apr 02 08:57:13 CST 2023
distributionBase=GRADLE_USER_HOME
-distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
From 4d914865f17e8ed070cca6c424cfeeaad3f65a00 Mon Sep 17 00:00:00 2001
From: gexinghai <2874903098@qq.com>
Date: Thu, 27 Apr 2023 14:42:56 +0800
Subject: [PATCH 7/7] =?UTF-8?q?=E6=96=B0=E5=A2=9E=203x3=E7=AA=97=E5=8F=A3?=
=?UTF-8?q?=E5=B0=8F=E9=83=A8=E4=BB=B6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/Notes/app/src/main/AndroidManifest.xml | 67 ++++++++++++-------
.../net/micode/notes/tool/ResourceParser.java | 14 ++++
.../net/micode/notes/ui/NoteEditActivity.java | 48 +++++++------
.../micode/notes/ui/NotesListActivity.java | 65 ++++++++++--------
.../notes/widget/NoteWidgetProvider_3x.java | 2 +-
.../src/main/res/values-zh-rCN/strings.xml | 1 +
.../src/main/res/values-zh-rTW/strings.xml | 1 +
src/Notes/app/src/main/res/values/strings.xml | 1 +
.../app/src/main/res/xml/widget_3x_info.xml | 9 +++
9 files changed, 133 insertions(+), 75 deletions(-)
create mode 100644 src/Notes/app/src/main/res/xml/widget_3x_info.xml
diff --git a/src/Notes/app/src/main/AndroidManifest.xml b/src/Notes/app/src/main/AndroidManifest.xml
index a30799f..96920fb 100644
--- a/src/Notes/app/src/main/AndroidManifest.xml
+++ b/src/Notes/app/src/main/AndroidManifest.xml
@@ -18,9 +18,10 @@
+ android:versionName="0.1">
-
@@ -36,19 +37,19 @@
+ android:label="@string/app_name">
-
-
+
+
+ android:windowSoftInputMode="adjustPan">
@@ -59,14 +60,16 @@
+ android:theme="@style/NoteTheme">
-
+
@@ -74,6 +77,7 @@
+
@@ -92,14 +96,14 @@
+ android:exported="false"
+ android:multiprocess="true" />
+ android:exported="true"
+ android:label="@string/app_widget2x2">
@@ -111,11 +115,27 @@
android:resource="@xml/widget_2x_info" />
+
+
+
+
+
+
+
+
+
+
+
+ android:exported="true"
+ android:label="@string/app_widget4x4">
@@ -129,7 +149,8 @@
-
@@ -138,26 +159,22 @@
-
+ android:process=":remote">
-
+ android:theme="@android:style/Theme.Holo.Wallpaper.NoTitleBar">
-
+ android:theme="@android:style/Theme.Holo.Light">
-
+ android:exported="false">
sBgSelectorBtnsMap = new HashMap();
+
static {
sBgSelectorBtnsMap.put(R.id.iv_bg_yellow, ResourceParser.YELLOW);
sBgSelectorBtnsMap.put(R.id.iv_bg_red, ResourceParser.RED);
@@ -95,6 +97,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}
private static final Map sBgSelectorSelectionMap = new HashMap();
+
static {
sBgSelectorSelectionMap.put(ResourceParser.YELLOW, R.id.iv_bg_yellow_select);
sBgSelectorSelectionMap.put(ResourceParser.RED, R.id.iv_bg_red_select);
@@ -105,6 +108,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
// sBgSelectorBtnsMap是一个HashMap,将用于选择背景颜色的ImageView视图的资源ID映射到整数值,这些整数值在ResourceParser类中定义。同样,sBgSelectorSelectionMap将整数值映射到所选ImageView视图的资源ID。
private static final Map sFontSizeBtnsMap = new HashMap();
+
static {
sFontSizeBtnsMap.put(R.id.ll_font_large, ResourceParser.TEXT_LARGE);
sFontSizeBtnsMap.put(R.id.ll_font_small, ResourceParser.TEXT_SMALL);
@@ -113,6 +117,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}
private static final Map sFontSelectorSelectionMap = new HashMap();
+
static {
sFontSelectorSelectionMap.put(ResourceParser.TEXT_LARGE, R.id.iv_large_select);
sFontSelectorSelectionMap.put(ResourceParser.TEXT_SMALL, R.id.iv_small_select);
@@ -224,7 +229,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN
| WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
- } else if(TextUtils.equals(Intent.ACTION_INSERT_OR_EDIT, intent.getAction())) {
+ } else if (TextUtils.equals(Intent.ACTION_INSERT_OR_EDIT, intent.getAction())) {
// New note 如果用户指定了 Intent.ACTION_INSERT_OR_EDIT 动作,则获取笔记ID,如果笔记ID存在,则加载笔记,否则,创建一个新的笔记
long folderId = intent.getLongExtra(Notes.INTENT_EXTRA_FOLDER_ID, 0);
int widgetId = intent.getIntExtra(Notes.INTENT_EXTRA_WIDGET_ID,
@@ -328,7 +333,8 @@ public class NoteEditActivity extends Activity implements OnClickListener,
// 如果mWorkingNote没有闹钟提醒,则将标题栏中的提醒日期文本和提醒图标设置为不可见。
mNoteHeaderHolder.tvAlertDate.setVisibility(View.GONE);
mNoteHeaderHolder.ivAlertIcon.setVisibility(View.GONE);
- };
+ }
+ ;
}
@Override
@@ -373,7 +379,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
private boolean inRangeOfView(View view, MotionEvent ev) {
// 获取视图在屏幕上的位置。
- int []location = new int[2];
+ int[] location = new int[2];
view.getLocationOnScreen(location);
int x = location[0];
int y = location[1];
@@ -382,8 +388,8 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|| ev.getX() > (x + view.getWidth())
|| ev.getY() < y
|| ev.getY() > (y + view.getHeight())) {
- return false;
- }
+ return false;
+ }
return true;
}
@@ -407,7 +413,8 @@ public class NoteEditActivity extends Activity implements OnClickListener,
for (int id : sFontSizeBtnsMap.keySet()) {
View view = findViewById(id);
view.setOnClickListener(this);
- };
+ }
+ ;
mSharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
mFontSizeId = mSharedPrefs.getInt(PREFERENCE_FONT_SIZE, ResourceParser.BG_DEFAULT_FONT_SIZE);
/*
@@ -415,7 +422,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
* The id may larger than the length of resources, in this case,
* return the {@link ResourceParser#BG_DEFAULT_FONT_SIZE}
*/
- if(mFontSizeId >= TextAppearanceResources.getResourcesSize()) {
+ if (mFontSizeId >= TextAppearanceResources.getResourcesSize()) {
mFontSizeId = ResourceParser.BG_DEFAULT_FONT_SIZE;
}
mEditTextList = (LinearLayout) findViewById(R.id.note_edit_list);
@@ -424,7 +431,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
@Override
protected void onPause() {
super.onPause();
- if(saveNote()) {
+ if (saveNote()) {
Log.d(TAG, "Note data was saved with length:" + mWorkingNote.getContent().length());
}
clearSettingState();
@@ -434,15 +441,17 @@ public class NoteEditActivity extends Activity implements OnClickListener,
Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
if (mWorkingNote.getWidgetType() == Notes.TYPE_WIDGET_2X) {
intent.setClass(this, NoteWidgetProvider_2x.class);
+ } else if (mWorkingNote.getWidgetType() == Notes.TYPE_WIDGET_3X) {
+ intent.setClass(this, NoteWidgetProvider_3x.class);
} else if (mWorkingNote.getWidgetType() == Notes.TYPE_WIDGET_4X) {
intent.setClass(this, NoteWidgetProvider_4x.class);
} else {
- Log.e(TAG, "Unspported widget type");
+ Log.e(TAG, "Unsupported widget type");
return;
}
- intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, new int[] {
- mWorkingNote.getWidgetId()
+ intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, new int[]{
+ mWorkingNote.getWidgetId()
});
sendBroadcast(intent);
@@ -450,13 +459,12 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}//updateWidget()方法更新与当前笔记相关联的小部件。它创建一个意图,并根据笔记的小部件类型设置相应的小部件提供程序类。然后它发送一个广播,带有小部件ID以更新小部件。
-
public void onClick(View v) {
int id = v.getId();
if (id == R.id.btn_set_bg_color) {
mNoteBgColorSelector.setVisibility(View.VISIBLE);
findViewById(sBgSelectorSelectionMap.get(mWorkingNote.getBgColorId())).setVisibility(
- - View.VISIBLE);
+ -View.VISIBLE);
} else if (sBgSelectorBtnsMap.containsKey(id)) {
findViewById(sBgSelectorSelectionMap.get(mWorkingNote.getBgColorId())).setVisibility(
View.GONE);
@@ -480,7 +488,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
@Override
public void onBackPressed() {
- if(clearSettingState()) {
+ if (clearSettingState()) {
return;
}
@@ -583,7 +591,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
DateTimePickerDialog d = new DateTimePickerDialog(this, System.currentTimeMillis());
d.setOnDateTimeSetListener(new OnDateTimeSetListener() {
public void OnDateTimeSet(AlertDialog dialog, long date) {
- mWorkingNote.setAlertDate(date , true);
+ mWorkingNote.setAlertDate(date, true);
}
});
d.show();
@@ -653,7 +661,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
AlarmManager alarmManager = ((AlarmManager) getSystemService(ALARM_SERVICE));
showAlertHeader();
- if(!set) {
+ if (!set) {
alarmManager.cancel(pendingIntent);
} else {
alarmManager.set(AlarmManager.RTC_WAKEUP, date, pendingIntent);
@@ -687,7 +695,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
mEditTextList.removeViewAt(index);
NoteEditText edit = null;
- if(index == 0) {
+ if (index == 0) {
edit = (NoteEditText) mEditTextList.getChildAt(0).findViewById(
R.id.et_edit_text);
} else {
@@ -705,7 +713,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
/**
* Should not happen, check for debug
*/
- if(index > mEditTextList.getChildCount()) {
+ if (index > mEditTextList.getChildCount()) {
Log.e(TAG, "Index out of mEditTextList boundrary, should not happen");
}
@@ -725,7 +733,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
String[] items = text.split("\n");
int index = 0;
for (String item : items) {
- if(!TextUtils.isEmpty(item)) {
+ if (!TextUtils.isEmpty(item)) {
mEditTextList.addView(getListItem(item, index));
index++;
}
@@ -793,7 +801,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
Log.e(TAG, "Wrong index, should not happen");
return;
}
- if(hasText) {
+ if (hasText) {
mEditTextList.getChildAt(index).findViewById(R.id.cb_edit_item).setVisibility(View.VISIBLE);
} else {
mEditTextList.getChildAt(index).findViewById(R.id.cb_edit_item).setVisibility(View.GONE);
diff --git a/src/Notes/app/src/main/java/net/micode/notes/ui/NotesListActivity.java b/src/Notes/app/src/main/java/net/micode/notes/ui/NotesListActivity.java
index 4d980ad..d059a71 100644
--- a/src/Notes/app/src/main/java/net/micode/notes/ui/NotesListActivity.java
+++ b/src/Notes/app/src/main/java/net/micode/notes/ui/NotesListActivity.java
@@ -70,6 +70,7 @@ import net.micode.notes.tool.DataUtils;
import net.micode.notes.tool.ResourceParser;
import net.micode.notes.ui.NotesListAdapter.AppWidgetAttribute;
import net.micode.notes.widget.NoteWidgetProvider_2x;
+import net.micode.notes.widget.NoteWidgetProvider_3x;
import net.micode.notes.widget.NoteWidgetProvider_4x;
import java.io.BufferedReader;
@@ -81,7 +82,7 @@ import java.util.HashSet;
public class NotesListActivity extends Activity implements OnClickListener, OnItemLongClickListener {
private static final int FOLDER_NOTE_LIST_QUERY_TOKEN = 0;
- private static final int FOLDER_LIST_QUERY_TOKEN = 1;
+ private static final int FOLDER_LIST_QUERY_TOKEN = 1;
private static final int MENU_FOLDER_DELETE = 0;
@@ -93,7 +94,9 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
private enum ListEditState {
NOTE_LIST, SUB_FOLDER, CALL_RECORD_FOLDER
- };
+ }
+
+ ;
private ListEditState mState;
@@ -133,7 +136,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
+ NoteColumns.NOTES_COUNT + ">0)";
private final static int REQUEST_CODE_OPEN_NODE = 102;
- private final static int REQUEST_CODE_NEW_NODE = 103;
+ private final static int REQUEST_CODE_NEW_NODE = 103;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -165,11 +168,11 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
StringBuilder sb = new StringBuilder();
InputStream in = null;
try {
- in = getResources().openRawResource(R.raw.introduction);
+ in = getResources().openRawResource(R.raw.introduction);
if (in != null) {
InputStreamReader isr = new InputStreamReader(in);
BufferedReader br = new BufferedReader(isr);
- char [] buf = new char[1024];
+ char[] buf = new char[1024];
int len = 0;
while ((len = br.read(buf)) > 0) {
sb.append(buf, 0, len);
@@ -182,7 +185,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
e.printStackTrace();
return;
} finally {
- if(in != null) {
+ if (in != null) {
try {
in.close();
} catch (IOException e) {
@@ -261,7 +264,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
mDropDownMenu = new DropdownMenu(NotesListActivity.this,
(Button) customView.findViewById(R.id.selection_menu),
R.menu.note_list_dropdown);
- mDropDownMenu.setOnDropdownMenuItemClickListener(new PopupMenu.OnMenuItemClickListener(){
+ mDropDownMenu.setOnDropdownMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
mNotesListAdapter.selectAll(!mNotesListAdapter.isAllSelected());
updateMenu();
@@ -311,7 +314,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
}//结束操作模式。该方法结束操作模式。
public void onItemCheckedStateChanged(ActionMode mode, int position, long id,
- boolean checked) {
+ boolean checked) {
mNotesListAdapter.setCheckedItem(position, checked);
updateMenu();
}//当用户选中或取消选中一个列表项时调用。该方法更新适配器中对应列表项的选中状态,并调用updateMenu()方法更新下拉菜单中的选项。
@@ -329,14 +332,14 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
builder.setTitle(getString(R.string.alert_title_delete));
builder.setIcon(android.R.drawable.ic_dialog_alert);
builder.setMessage(getString(R.string.alert_message_delete_notes,
- mNotesListAdapter.getSelectedCount()));
+ mNotesListAdapter.getSelectedCount()));
builder.setPositiveButton(android.R.string.ok,
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog,
- int which) {
- batchDelete();
- }
- });
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog,
+ int which) {
+ batchDelete();
+ }
+ });
builder.setNegativeButton(android.R.string.cancel, null);
builder.show();
break;
@@ -411,25 +414,27 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
return false;
}
- };
+ }
+
+ ;
private void startAsyncNotesListQuery() {
String selection = (mCurrentFolderId == Notes.ID_ROOT_FOLDER) ? ROOT_FOLDER_SELECTION
: NORMAL_SELECTION;
mBackgroundQueryHandler.startQuery(FOLDER_NOTE_LIST_QUERY_TOKEN, null,
- Notes.CONTENT_NOTE_URI, NoteItemData.PROJECTION, selection, new String[] {
- String.valueOf(mCurrentFolderId)
+ Notes.CONTENT_NOTE_URI, NoteItemData.PROJECTION, selection, new String[]{
+ String.valueOf(mCurrentFolderId)
}, NoteColumns.TYPE + " DESC," + NoteColumns.MODIFIED_DATE + " DESC");
}
-// 后台查询处理程序,继承自AsyncQueryHandler
+ // 后台查询处理程序,继承自AsyncQueryHandler
private final class BackgroundQueryHandler extends AsyncQueryHandler {
public BackgroundQueryHandler(ContentResolver contentResolver) {
super(contentResolver);
}
// 构造函数,调用父类AsyncQueryHandler的构造函数
- // 查询完成后的回调函数,根据token值进行不同的处理
+ // 查询完成后的回调函数,根据token值进行不同的处理
@Override
protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
switch (token) {
@@ -634,7 +639,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
});
final Dialog dialog = builder.setView(view).show();
- final Button positive = (Button)dialog.findViewById(android.R.id.button1);
+ final Button positive = (Button) dialog.findViewById(android.R.id.button1);
positive.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
hideSoftInput(etName);
@@ -652,8 +657,8 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
values.put(NoteColumns.TYPE, Notes.TYPE_FOLDER);
values.put(NoteColumns.LOCAL_MODIFIED, 1);
mContentResolver.update(Notes.CONTENT_NOTE_URI, values, NoteColumns.ID
- + "=?", new String[] {
- String.valueOf(mFocusNoteDataItem.getId())
+ + "=?", new String[]{
+ String.valueOf(mFocusNoteDataItem.getId())
});
}
} else if (!TextUtils.isEmpty(name)) {
@@ -722,15 +727,17 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
if (appWidgetType == Notes.TYPE_WIDGET_2X) {
intent.setClass(this, NoteWidgetProvider_2x.class);
+ } else if (appWidgetType == Notes.TYPE_WIDGET_3X) {
+ intent.setClass(this, NoteWidgetProvider_3x.class);
} else if (appWidgetType == Notes.TYPE_WIDGET_4X) {
intent.setClass(this, NoteWidgetProvider_4x.class);
} else {
- Log.e(TAG, "Unspported widget type");
+ Log.e(TAG, "Unsupported widget type");
return;
}
- intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, new int[] {
- appWidgetId
+ intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, new int[]{
+ appWidgetId
});
sendBroadcast(intent);
@@ -958,15 +965,15 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
private void startQueryDestinationFolders() {
String selection = NoteColumns.TYPE + "=? AND " + NoteColumns.PARENT_ID + "<>? AND " + NoteColumns.ID + "<>?";
- selection = (mState == ListEditState.NOTE_LIST) ? selection:
- "(" + selection + ") OR (" + NoteColumns.ID + "=" + Notes.ID_ROOT_FOLDER + ")";
+ selection = (mState == ListEditState.NOTE_LIST) ? selection :
+ "(" + selection + ") OR (" + NoteColumns.ID + "=" + Notes.ID_ROOT_FOLDER + ")";
mBackgroundQueryHandler.startQuery(FOLDER_LIST_QUERY_TOKEN,
null,
Notes.CONTENT_NOTE_URI,
FoldersListAdapter.PROJECTION,
selection,
- new String[] {
+ new String[]{
String.valueOf(Notes.TYPE_FOLDER),
String.valueOf(Notes.ID_TRASH_FOLER),
String.valueOf(mCurrentFolderId)
diff --git a/src/Notes/app/src/main/java/net/micode/notes/widget/NoteWidgetProvider_3x.java b/src/Notes/app/src/main/java/net/micode/notes/widget/NoteWidgetProvider_3x.java
index 9626f78..d7ddbd8 100644
--- a/src/Notes/app/src/main/java/net/micode/notes/widget/NoteWidgetProvider_3x.java
+++ b/src/Notes/app/src/main/java/net/micode/notes/widget/NoteWidgetProvider_3x.java
@@ -21,7 +21,7 @@ public class NoteWidgetProvider_3x extends NoteWidgetProvider{ // 3x3大小的
@Override // 重写窗口小部件中的获取资源ID函数
protected int getBgResourceId(int bgId) {
- return ResourceParser.WidgetBgResources.getWidget2xBgResource(bgId);
+ return ResourceParser.WidgetBgResources.getWidget3xBgResource(bgId);
}
@Override // 重写窗口小部件中的获取宽度类型函数
diff --git a/src/Notes/app/src/main/res/values-zh-rCN/strings.xml b/src/Notes/app/src/main/res/values-zh-rCN/strings.xml
index 09f75ed..b360297 100644
--- a/src/Notes/app/src/main/res/values-zh-rCN/strings.xml
+++ b/src/Notes/app/src/main/res/values-zh-rCN/strings.xml
@@ -19,6 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
便签
便签2x2
+ 便签3x3
便签4x4
没有关联内容,点击新建便签。
访客模式下,便签内容不可见
diff --git a/src/Notes/app/src/main/res/values-zh-rTW/strings.xml b/src/Notes/app/src/main/res/values-zh-rTW/strings.xml
index e29b79b..5eb467b 100644
--- a/src/Notes/app/src/main/res/values-zh-rTW/strings.xml
+++ b/src/Notes/app/src/main/res/values-zh-rTW/strings.xml
@@ -19,6 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
便簽
便簽2x2
+ 便簽3x3
便簽4x4
沒有關聯內容,點擊新建便簽。
訪客模式下,便籤內容不可見
diff --git a/src/Notes/app/src/main/res/values/strings.xml b/src/Notes/app/src/main/res/values/strings.xml
index 55df868..7d941bb 100644
--- a/src/Notes/app/src/main/res/values/strings.xml
+++ b/src/Notes/app/src/main/res/values/strings.xml
@@ -19,6 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
Notes
Notes 2x2
+ Notes 3x3
Notes 4x4
No associated note found, click to create associated note.
Privacy mode,can not see note content
diff --git a/src/Notes/app/src/main/res/xml/widget_3x_info.xml b/src/Notes/app/src/main/res/xml/widget_3x_info.xml
new file mode 100644
index 0000000..03936e4
--- /dev/null
+++ b/src/Notes/app/src/main/res/xml/widget_3x_info.xml
@@ -0,0 +1,9 @@
+
+
+
+
+