Android 垃圾分类APP(二)垃圾分类之手动输入

简介: Android 垃圾分类APP(二)垃圾分类之手动输入

前言


 在上一篇文章中进行了项目的搭建和网络请求的测试,还不错相信你一定可以完成。


正文


 这篇文章要做的就是手动输入物品去完成垃圾分类的结果显示,也不会很难,我会讲的细一点。


一、修改样式


先配置一些资源,找到你的res下的styles.xml,改成NoActionBar。


20210330165336759.png


然后打开colors.xml,里面的代码如下:


<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#505F98</color>
    <color name="colorPrimaryDark">#505F98</color>
    <color name="colorAccent">#D81B60</color>
    <color name="white">#FFF</color>
    <color name="white_50">#50FFFFFF</color>
    <color name="black">#000</color>
    <color name="search_bg_color">#F9F9FB</color>
    <color name="line_color">#EEEEEE</color>
    <color name="hint_color">#929299</color>
    <color name="blue_top">#4B649C</color>
    <color name="blue">#00A6D9</color>
</resources>


然后在values文件夹下新建一个dimen.xml,里面的代码如下:


<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools">
    <dimen name="alert_width">290dp</dimen>
    <dimen name="common_circle_width">3dp</dimen>
    <dimen name="progress_circle_radius">34dp</dimen>
    <dimen name="font_9sp">9sp</dimen>
    <dimen name="font_10sp">10sp</dimen>
    <dimen name="font_11sp">11sp</dimen>
    <dimen name="font_12sp">12sp</dimen>
    <dimen name="font_13sp">13sp</dimen>
    <dimen name="font_14sp">14sp</dimen>
    <dimen name="font_15sp">15sp</dimen>
    <dimen name="font_16sp">16sp</dimen>
    <dimen name="font_17sp">17sp</dimen>
    <dimen name="font_18sp">18sp</dimen>
    <dimen name="font_20sp">20sp</dimen>
    <dimen name="font_21sp">21sp</dimen>
    <dimen name="font_23sp">23sp</dimen>
    <dimen name="font_24sp">24sp</dimen>
    <dimen name="font_27sp">27sp</dimen>
    <dimen name="font_28sp">28sp</dimen>
    <dimen name="font_33sp">33sp</dimen>
    <!-- Default screen margins, per the Android Design guidelines. -->
    <dimen name="activity_horizontal_margin">16dp</dimen>
    <dimen name="activity_vertical_margin">16dp</dimen>
    <dimen name="titil_view_height">50dp</dimen>
    <dimen name="dp_0">0dp</dimen>
    <dimen name="dp_0_1">0.1dp</dimen>
    <dimen name="dp_0_5">0.5dp</dimen>
    <dimen name="dp_1">1dp</dimen>
    <dimen name="dp_1_5">1.5dp</dimen>
    <dimen name="dp_2">2dp</dimen>
    <dimen name="dp_2_5">2.5dp</dimen>
    <dimen name="dp_3">3dp</dimen>
    <dimen name="dp_3_5">3.5dp</dimen>
    <dimen name="dp_4">4dp</dimen>
    <dimen name="dp_4_5">4.5dp</dimen>
    <dimen name="dp_5">5dp</dimen>
    <dimen name="dp_6">6dp</dimen>
    <dimen name="dp_7">7dp</dimen>
    <dimen name="dp_8">8dp</dimen>
    <dimen name="dp_9">9dp</dimen>
    <dimen name="dp_10">10dp</dimen>
    <dimen name="dp_11">11dp</dimen>
    <dimen name="dp_12">12dp</dimen>
    <dimen name="dp_13">13dp</dimen>
    <dimen name="dp_14">14dp</dimen>
    <dimen name="dp_15">15dp</dimen>
    <dimen name="dp_16">16dp</dimen>
    <dimen name="dp_17">17dp</dimen>
    <dimen name="dp_18">18dp</dimen>
    <dimen name="dp_19">19dp</dimen>
    <dimen name="dp_20">20dp</dimen>
    <dimen name="dp_21">21dp</dimen>
    <dimen name="dp_22">22dp</dimen>
    <dimen name="dp_23">23dp</dimen>
    <dimen name="dp_24">24dp</dimen>
    <dimen name="dp_25">25dp</dimen>
    <dimen name="dp_26">26dp</dimen>
    <dimen name="dp_27">27dp</dimen>
    <dimen name="dp_28">28dp</dimen>
    <dimen name="dp_29">29dp</dimen>
    <dimen name="dp_30">30dp</dimen>
    <dimen name="dp_31">31dp</dimen>
    <dimen name="dp_32">32dp</dimen>
    <dimen name="dp_33">33dp</dimen>
    <dimen name="dp_34">34dp</dimen>
    <dimen name="dp_35">35dp</dimen>
    <dimen name="dp_36">36dp</dimen>
    <dimen name="dp_37">37dp</dimen>
    <dimen name="dp_38">38dp</dimen>
    <dimen name="dp_39">39dp</dimen>
    <dimen name="dp_40">40dp</dimen>
    <dimen name="dp_41">41dp</dimen>
    <dimen name="dp_42">42dp</dimen>
    <dimen name="dp_43">43dp</dimen>
    <dimen name="dp_44">44dp</dimen>
    <dimen name="dp_45">45dp</dimen>
    <dimen name="dp_46">46dp</dimen>
    <dimen name="dp_47">47dp</dimen>
    <dimen name="dp_48">48dp</dimen>
    <dimen name="dp_49">49dp</dimen>
    <dimen name="dp_50">50dp</dimen>
    <dimen name="dp_51">51dp</dimen>
    <dimen name="dp_52">52dp</dimen>
    <dimen name="dp_53">53dp</dimen>
    <dimen name="dp_54">54dp</dimen>
    <dimen name="dp_55">55dp</dimen>
    <dimen name="dp_56">56dp</dimen>
    <dimen name="dp_57">57dp</dimen>
    <dimen name="dp_58">58dp</dimen>
    <dimen name="dp_59">59dp</dimen>
    <dimen name="dp_60">60dp</dimen>
    <dimen name="dp_61">61dp</dimen>
    <dimen name="dp_62">62dp</dimen>
    <dimen name="dp_63">63dp</dimen>
    <dimen name="dp_64">64dp</dimen>
    <dimen name="dp_65">65dp</dimen>
    <dimen name="dp_66">66dp</dimen>
    <dimen name="dp_67">67dp</dimen>
    <dimen name="dp_68">68dp</dimen>
    <dimen name="dp_69">69dp</dimen>
    <dimen name="dp_70">70dp</dimen>
    <dimen name="dp_71">71dp</dimen>
    <dimen name="dp_72">72dp</dimen>
    <dimen name="dp_73">73dp</dimen>
    <dimen name="dp_74">74dp</dimen>
    <dimen name="dp_75">75dp</dimen>
    <dimen name="dp_76">76dp</dimen>
    <dimen name="dp_77">77dp</dimen>
    <dimen name="dp_78">78dp</dimen>
    <dimen name="dp_79">79dp</dimen>
    <dimen name="dp_80">80dp</dimen>
    <dimen name="dp_81">81dp</dimen>
    <dimen name="dp_82">82dp</dimen>
    <dimen name="dp_83">83dp</dimen>
    <dimen name="dp_84">84dp</dimen>
    <dimen name="dp_85">85dp</dimen>
    <dimen name="dp_86">86dp</dimen>
    <dimen name="dp_87">87dp</dimen>
    <dimen name="dp_88">88dp</dimen>
    <dimen name="dp_89">89dp</dimen>
    <dimen name="dp_90">90dp</dimen>
    <dimen name="dp_91">91dp</dimen>
    <dimen name="dp_92">92dp</dimen>
    <dimen name="dp_93">93dp</dimen>
    <dimen name="dp_94">94dp</dimen>
    <dimen name="dp_95">95dp</dimen>
    <dimen name="dp_96">96dp</dimen>
    <dimen name="dp_97">97dp</dimen>
    <dimen name="dp_98">98dp</dimen>
    <dimen name="dp_99">99dp</dimen>
    <dimen name="dp_100">100dp</dimen>
    <dimen name="dp_101">101dp</dimen>
    <dimen name="dp_102">102dp</dimen>
    <dimen name="dp_103">103dp</dimen>
    <dimen name="dp_104">104dp</dimen>
    <dimen name="dp_105">105dp</dimen>
    <dimen name="dp_106">106dp</dimen>
    <dimen name="dp_107">107dp</dimen>
    <dimen name="dp_108">108dp</dimen>
    <dimen name="dp_109">109dp</dimen>
    <dimen name="dp_110">110dp</dimen>
    <dimen name="dp_111">111dp</dimen>
    <dimen name="dp_112">112dp</dimen>
    <dimen name="dp_113">113dp</dimen>
    <dimen name="dp_114">114dp</dimen>
    <dimen name="dp_115">115dp</dimen>
    <dimen name="dp_116">116dp</dimen>
    <dimen name="dp_117">117dp</dimen>
    <dimen name="dp_118">118dp</dimen>
    <dimen name="dp_119">119dp</dimen>
    <dimen name="dp_120">120dp</dimen>
    <dimen name="dp_121">121dp</dimen>
    <dimen name="dp_122">122dp</dimen>
    <dimen name="dp_123">123dp</dimen>
    <dimen name="dp_124">124dp</dimen>
    <dimen name="dp_125">125dp</dimen>
    <dimen name="dp_126">126dp</dimen>
    <dimen name="dp_127">127dp</dimen>
    <dimen name="dp_128">128dp</dimen>
    <dimen name="dp_129">129dp</dimen>
    <dimen name="dp_130">130dp</dimen>
    <dimen name="dp_131">131dp</dimen>
    <dimen name="dp_132">132dp</dimen>
    <dimen name="dp_133">133dp</dimen>
    <dimen name="dp_134">134dp</dimen>
    <dimen name="dp_135">135dp</dimen>
    <dimen name="dp_136">136dp</dimen>
    <dimen name="dp_137">137dp</dimen>
    <dimen name="dp_138">138dp</dimen>
    <dimen name="dp_139">139dp</dimen>
    <dimen name="dp_140">140dp</dimen>
    <dimen name="dp_141">141dp</dimen>
    <dimen name="dp_142">142dp</dimen>
    <dimen name="dp_143">143dp</dimen>
    <dimen name="dp_144">144dp</dimen>
    <dimen name="dp_145">145dp</dimen>
    <dimen name="dp_146">146dp</dimen>
    <dimen name="dp_147">147dp</dimen>
    <dimen name="dp_148">148dp</dimen>
    <dimen name="dp_149">149dp</dimen>
    <dimen name="dp_150">150dp</dimen>
    <dimen name="dp_151">151dp</dimen>
    <dimen name="dp_152">152dp</dimen>
    <dimen name="dp_153">153dp</dimen>
    <dimen name="dp_154">154dp</dimen>
    <dimen name="dp_155">155dp</dimen>
    <dimen name="dp_156">156dp</dimen>
    <dimen name="dp_157">157dp</dimen>
    <dimen name="dp_158">158dp</dimen>
    <dimen name="dp_159">159dp</dimen>
    <dimen name="dp_160">160dp</dimen>
    <dimen name="dp_161">161dp</dimen>
    <dimen name="dp_162">162dp</dimen>
    <dimen name="dp_163">163dp</dimen>
    <dimen name="dp_164">164dp</dimen>
    <dimen name="dp_165">165dp</dimen>
    <dimen name="dp_166">166dp</dimen>
    <dimen name="dp_167">167dp</dimen>
    <dimen name="dp_168">168dp</dimen>
    <dimen name="dp_169">169dp</dimen>
    <dimen name="dp_170">170dp</dimen>
    <dimen name="dp_171">171dp</dimen>
    <dimen name="dp_172">172dp</dimen>
    <dimen name="dp_173">173dp</dimen>
    <dimen name="dp_174">174dp</dimen>
    <dimen name="dp_175">175dp</dimen>
    <dimen name="dp_176">176dp</dimen>
    <dimen name="dp_177">177dp</dimen>
    <dimen name="dp_178">178dp</dimen>
    <dimen name="dp_179">179dp</dimen>
    <dimen name="dp_180">180dp</dimen>
    <dimen name="dp_181">181dp</dimen>
    <dimen name="dp_182">182dp</dimen>
    <dimen name="dp_183">183dp</dimen>
    <dimen name="dp_184">184dp</dimen>
    <dimen name="dp_185">185dp</dimen>
    <dimen name="dp_186">186dp</dimen>
    <dimen name="dp_187">187dp</dimen>
    <dimen name="dp_188">188dp</dimen>
    <dimen name="dp_189">189dp</dimen>
    <dimen name="dp_190">190dp</dimen>
    <dimen name="dp_191">191dp</dimen>
    <dimen name="dp_192">192dp</dimen>
    <dimen name="dp_193">193dp</dimen>
    <dimen name="dp_194">194dp</dimen>
    <dimen name="dp_195">195dp</dimen>
    <dimen name="dp_196">196dp</dimen>
    <dimen name="dp_197">197dp</dimen>
    <dimen name="dp_198">198dp</dimen>
    <dimen name="dp_199">199dp</dimen>
    <dimen name="dp_200">200dp</dimen>
    <dimen name="dp_201">201dp</dimen>
    <dimen name="dp_202">202dp</dimen>
    <dimen name="dp_203">203dp</dimen>
    <dimen name="dp_204">204dp</dimen>
    <dimen name="dp_205">205dp</dimen>
    <dimen name="dp_206">206dp</dimen>
    <dimen name="dp_207">207dp</dimen>
    <dimen name="dp_208">208dp</dimen>
    <dimen name="dp_209">209dp</dimen>
    <dimen name="dp_210">210dp</dimen>
    <dimen name="dp_211">211dp</dimen>
    <dimen name="dp_212">212dp</dimen>
    <dimen name="dp_213">213dp</dimen>
    <dimen name="dp_214">214dp</dimen>
    <dimen name="dp_215">215dp</dimen>
    <dimen name="dp_216">216dp</dimen>
    <dimen name="dp_217">217dp</dimen>
    <dimen name="dp_218">218dp</dimen>
    <dimen name="dp_219">219dp</dimen>
    <dimen name="dp_220">220dp</dimen>
    <dimen name="dp_221">221dp</dimen>
    <dimen name="dp_222">222dp</dimen>
    <dimen name="dp_223">223dp</dimen>
    <dimen name="dp_224">224dp</dimen>
    <dimen name="dp_225">225dp</dimen>
    <dimen name="dp_226">226dp</dimen>
    <dimen name="dp_227">227dp</dimen>
    <dimen name="dp_228">228dp</dimen>
    <dimen name="dp_229">229dp</dimen>
    <dimen name="dp_230">230dp</dimen>
    <dimen name="dp_231">231dp</dimen>
    <dimen name="dp_232">232dp</dimen>
    <dimen name="dp_233">233dp</dimen>
    <dimen name="dp_234">234dp</dimen>
    <dimen name="dp_235">235dp</dimen>
    <dimen name="dp_236">236dp</dimen>
    <dimen name="dp_237">237dp</dimen>
    <dimen name="dp_238">238dp</dimen>
    <dimen name="dp_239">239dp</dimen>
    <dimen name="dp_240">240dp</dimen>
    <dimen name="dp_241">241dp</dimen>
    <dimen name="dp_242">242dp</dimen>
    <dimen name="dp_243">243dp</dimen>
    <dimen name="dp_244">244dp</dimen>
    <dimen name="dp_245">245dp</dimen>
    <dimen name="dp_246">246dp</dimen>
    <dimen name="dp_247">247dp</dimen>
    <dimen name="dp_248">248dp</dimen>
    <dimen name="dp_249">249dp</dimen>
    <dimen name="dp_250">250dp</dimen>
    <dimen name="dp_251">251dp</dimen>
    <dimen name="dp_252">252dp</dimen>
    <dimen name="dp_253">253dp</dimen>
    <dimen name="dp_254">254dp</dimen>
    <dimen name="dp_255">255dp</dimen>
    <dimen name="dp_256">256dp</dimen>
    <dimen name="dp_257">257dp</dimen>
    <dimen name="dp_258">258dp</dimen>
    <dimen name="dp_259">259dp</dimen>
    <dimen name="dp_260">260dp</dimen>
    <dimen name="dp_261">261dp</dimen>
    <dimen name="dp_262">262dp</dimen>
    <dimen name="dp_263">263dp</dimen>
    <dimen name="dp_264">264dp</dimen>
    <dimen name="dp_265">265dp</dimen>
    <dimen name="dp_266">266dp</dimen>
    <dimen name="dp_267">267dp</dimen>
    <dimen name="dp_268">268dp</dimen>
    <dimen name="dp_269">269dp</dimen>
    <dimen name="dp_270">270dp</dimen>
    <dimen name="dp_271">271dp</dimen>
    <dimen name="dp_272">272dp</dimen>
    <dimen name="dp_273">273dp</dimen>
    <dimen name="dp_274">274dp</dimen>
    <dimen name="dp_275">275dp</dimen>
    <dimen name="dp_276">276dp</dimen>
    <dimen name="dp_277">277dp</dimen>
    <dimen name="dp_278">278dp</dimen>
    <dimen name="dp_279">279dp</dimen>
    <dimen name="dp_280">280dp</dimen>
    <dimen name="dp_281">281dp</dimen>
    <dimen name="dp_282">282dp</dimen>
    <dimen name="dp_283">283dp</dimen>
    <dimen name="dp_284">284dp</dimen>
    <dimen name="dp_285">285dp</dimen>
    <dimen name="dp_286">286dp</dimen>
    <dimen name="dp_287">287dp</dimen>
    <dimen name="dp_288">288dp</dimen>
    <dimen name="dp_289">289dp</dimen>
    <dimen name="dp_290">290dp</dimen>
    <dimen name="dp_291">291dp</dimen>
    <dimen name="dp_292">292dp</dimen>
    <dimen name="dp_293">293dp</dimen>
    <dimen name="dp_294">294dp</dimen>
    <dimen name="dp_295">295dp</dimen>
    <dimen name="dp_296">296dp</dimen>
    <dimen name="dp_297">297dp</dimen>
    <dimen name="dp_298">298dp</dimen>
    <dimen name="dp_299">299dp</dimen>
    <dimen name="dp_300">300dp</dimen>
    <dimen name="dp_301">301dp</dimen>
    <dimen name="dp_302">302dp</dimen>
    <dimen name="dp_303">303dp</dimen>
    <dimen name="dp_304">304dp</dimen>
    <dimen name="dp_305">305dp</dimen>
    <dimen name="dp_306">306dp</dimen>
    <dimen name="dp_307">307dp</dimen>
    <dimen name="dp_308">308dp</dimen>
    <dimen name="dp_309">309dp</dimen>
    <dimen name="dp_310">310dp</dimen>
    <dimen name="dp_311">311dp</dimen>
    <dimen name="dp_312">312dp</dimen>
    <dimen name="dp_313">313dp</dimen>
    <dimen name="dp_314">314dp</dimen>
    <dimen name="dp_315">315dp</dimen>
    <dimen name="dp_316">316dp</dimen>
    <dimen name="dp_317">317dp</dimen>
    <dimen name="dp_318">318dp</dimen>
    <dimen name="dp_319">319dp</dimen>
    <dimen name="dp_320">320dp</dimen>
    <dimen name="dp_321">321dp</dimen>
    <dimen name="dp_322">322dp</dimen>
    <dimen name="dp_323">323dp</dimen>
    <dimen name="dp_324">324dp</dimen>
    <dimen name="dp_325">325dp</dimen>
    <dimen name="dp_326">326dp</dimen>
    <dimen name="dp_327">327dp</dimen>
    <dimen name="dp_328">328dp</dimen>
    <dimen name="dp_329">329dp</dimen>
    <dimen name="dp_330">330dp</dimen>
    <dimen name="dp_331">331dp</dimen>
    <dimen name="dp_332">332dp</dimen>
    <dimen name="dp_333">333dp</dimen>
    <dimen name="dp_334">334dp</dimen>
    <dimen name="dp_335">335dp</dimen>
    <dimen name="dp_336">336dp</dimen>
    <dimen name="dp_337">337dp</dimen>
    <dimen name="dp_338">338dp</dimen>
    <dimen name="dp_339">339dp</dimen>
    <dimen name="dp_340">340dp</dimen>
    <dimen name="dp_341">341dp</dimen>
    <dimen name="dp_342">342dp</dimen>
    <dimen name="dp_343">343dp</dimen>
    <dimen name="dp_344">344dp</dimen>
    <dimen name="dp_345">345dp</dimen>
    <dimen name="dp_346">346dp</dimen>
    <dimen name="dp_347">347dp</dimen>
    <dimen name="dp_348">348dp</dimen>
    <dimen name="dp_349">349dp</dimen>
    <dimen name="dp_350">350dp</dimen>
    <dimen name="dp_351">351dp</dimen>
    <dimen name="dp_352">352dp</dimen>
    <dimen name="dp_353">353dp</dimen>
    <dimen name="dp_354">354dp</dimen>
    <dimen name="dp_355">355dp</dimen>
    <dimen name="dp_356">356dp</dimen>
    <dimen name="dp_357">357dp</dimen>
    <dimen name="dp_358">358dp</dimen>
    <dimen name="dp_359">359dp</dimen>
    <dimen name="dp_360">360dp</dimen>
    <dimen name="dp_365">365dp</dimen>
    <dimen name="dp_370">370dp</dimen>
    <dimen name="dp_399">399dp</dimen>
    <dimen name="dp_400">400dp</dimen>
    <dimen name="dp_410">410dp</dimen>
    <dimen name="dp_420">420dp</dimen>
    <dimen name="dp_412">412dp</dimen>
    <dimen name="dp_422">422dp</dimen>
    <dimen name="dp_472">472dp</dimen>
    <dimen name="dp_500">500dp</dimen>
    <dimen name="dp_520">520dp</dimen>
    <dimen name="dp_550">550dp</dimen>
    <dimen name="dp_560">560dp</dimen>
    <dimen name="dp_600">600dp</dimen>
    <dimen name="dp_640">640dp</dimen>
    <dimen name="dp_720">720dp</dimen>
    <!-- fonts size,you can add if there is no one -->
    <dimen name="sp_6">6sp</dimen>
    <dimen name="sp_7">7sp</dimen>
    <dimen name="sp_8">8sp</dimen>
    <dimen name="sp_9">9sp</dimen>
    <dimen name="sp_10">10sp</dimen>
    <dimen name="sp_11">11sp</dimen>
    <dimen name="sp_12">12sp</dimen>
    <dimen name="sp_13">13sp</dimen>
    <dimen name="sp_14">14sp</dimen>
    <dimen name="sp_15">15sp</dimen>
    <dimen name="sp_16">16sp</dimen>
    <dimen name="sp_17">17sp</dimen>
    <dimen name="sp_18">18sp</dimen>
    <dimen name="sp_19">19sp</dimen>
    <dimen name="sp_20">20sp</dimen>
    <dimen name="sp_21">21sp</dimen>
    <dimen name="sp_22">22sp</dimen>
    <dimen name="sp_23">23sp</dimen>
    <dimen name="sp_24">24sp</dimen>
    <dimen name="sp_25">25sp</dimen>
    <dimen name="sp_26">26sp</dimen>
    <dimen name="sp_27">27sp</dimen>
    <dimen name="sp_28">28sp</dimen>
    <dimen name="sp_29">29sp</dimen>
    <dimen name="sp_30">30sp</dimen>
    <dimen name="sp_31">31sp</dimen>
    <dimen name="sp_32">32sp</dimen>
    <dimen name="sp_33">33sp</dimen>
    <dimen name="sp_34">34sp</dimen>
    <dimen name="sp_35">35sp</dimen>
    <dimen name="sp_36">36sp</dimen>
    <dimen name="sp_37">37sp</dimen>
    <dimen name="sp_38">38sp</dimen>
    <dimen name="sp_40">40sp</dimen>
    <dimen name="sp_42">42sp</dimen>
    <dimen name="sp_48">48sp</dimen>
    <dimen name="crumb_view_padding">12dp</dimen>
</resources>


二、修改布局


在修改布局之前,先准备好需要的资源,首先是两个图标

20210330165825570.png

20210330165825572.png


在drawable中新建search_et_bg.xml,里面的代码如下:


<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="@color/search_bg_color"/>
    <corners android:radius="8dp"/>
</shape>


这是设置输入框的背景

然后再新建一个cursor_style.xml,里面的代码如下:


<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <size android:width="@dimen/dp_1" />
    <solid android:color="@color/black" />
</shape>


这是设置输入框的光标颜色。

下面可以写布局了。


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    android:orientation="vertical"
    tools:context=".MainActivity">
    <!--标题-->
    <com.google.android.material.appbar.MaterialToolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/colorPrimaryDark">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:text="垃圾分类"
            android:textColor="@color/white"
            android:textSize="18sp" />
    </com.google.android.material.appbar.MaterialToolbar>
    <!--搜索物品布局-->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/white">
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="36dp"
            android:layout_marginStart="@dimen/sp_16"
            android:layout_marginTop="@dimen/dp_12"
            android:layout_marginEnd="@dimen/dp_16"
            android:layout_marginBottom="@dimen/dp_12"
            android:background="@drawable/search_et_bg"
            android:orientation="horizontal">
            <ImageView
                android:id="@+id/iv_search"
                android:layout_width="@dimen/dp_16"
                android:layout_height="@dimen/dp_16"
                android:layout_centerVertical="true"
                android:layout_marginStart="@dimen/dp_12"
                android:layout_marginEnd="@dimen/dp_8"
                app:srcCompat="@mipmap/icon_search" />
            <EditText
                android:id="@+id/et_goods"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_toStartOf="@+id/iv_clear"
                android:layout_toEndOf="@+id/iv_search"
                android:background="@null"
                android:hint="请输入物品"
                android:imeOptions="actionSearch"
                android:singleLine="true"
                android:textColor="@color/black"
                android:textColorHint="@color/hint_color"
                android:textCursorDrawable="@drawable/cursor_style"
                android:textSize="@dimen/sp_14" />
            <ImageView
                android:id="@+id/iv_clear"
                android:layout_width="@dimen/dp_36"
                android:layout_height="@dimen/dp_36"
                android:layout_alignParentEnd="true"
                android:padding="@dimen/dp_10"
                android:src="@mipmap/icon_clear"
                android:visibility="invisible" />
        </RelativeLayout>
    </LinearLayout>
    <!--列表-->
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rv_result"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:overScrollMode="never"
        android:scrollbars="none" />
</LinearLayout>


三、使用Mvp框架


下面设置接口的访问地址,打开mvplibrary下的NetworkApi类,修改正式环境的访问地址


mBaseUrl = "http://api.tianapi.com";


如下图所示


20210330171212313.png


下面回到app模块,在com.llw.goodtrash包下新建NetworkRequiredInfo类,里面代码如下;


package com.llw.goodtrash;
import android.app.Application;
import com.llw.mvplibrary.BuildConfig;
import com.llw.mvplibrary.network.INetworkRequiredInfo;
/**
 * 网络访问信息
 * @author llw
 */
public class NetworkRequiredInfo implements INetworkRequiredInfo {
    private Application application;
    public NetworkRequiredInfo(Application application){
        this.application = application;
    }
    /**
     * 版本名
     */
    @Override
    public String getAppVersionName() {
        return BuildConfig.VERSION_NAME;
    }
    /**
     * 版本号
     */
    @Override
    public String getAppVersionCode() {
        return String.valueOf(BuildConfig.VERSION_CODE);
    }
    /**
     * 是否为debug
     */
    @Override
    public boolean isDebug() {
        return BuildConfig.DEBUG;
    }
    /**
     * 应用全局上下文
     */
    @Override
    public Application getApplicationContext() {
        return application;
    }
}


之后再新建一个TrashApplication类,代码如下:


package com.llw.goodtrash;
import com.llw.mvplibrary.BaseApplication;
import com.llw.mvplibrary.network.NetworkApi;
/**
 * 自定义Application
 */
public class TrashApplication extends BaseApplication {
    @Override
    public void onCreate() {
        super.onCreate();
        //初始化网络框架
        NetworkApi.init(new NetworkRequiredInfo(this));
    }
}


自定义的Application需要到AndroidManifest.xml中去配置才会生效,如下图所示:


2021060720230069.png


现在你就可以访问网络了,这虽然看起来是单独使用Okhttp要麻烦,但实际上是要方便很多的,你可能现在不明白,以后你会懂得。


我在天行API中请求接口使用的KEY,这里我新建了一个全局常量类,放在里面,在com.llw.goodtrash包下新建一个utils包。包下的代码如下:


package com.llw.goodtrash.utils;
/**
 * 全局常量
 *
 * @author llw
 * @date 2021/3/30 15:14
 */
public class Constant {
    /**
     * 垃圾分类的key  请替换为自己的
     */
    public static final String KEY = "783da68c7ea7e10fcd259db651cc550b";
    /**
     * 请求成功码
     */
    public static final int SUCCESS_CODE = 200;
}


之前通过返回的数据可以生成一个返回数据实体,在com.llw.goodtrash包下新建一个model包,包下新建一个TrashResponse类,代码如下:


package com.llw.goodtrash.model;
import java.util.List;
/**
 * 垃圾分类返回数据
 */
public class TrashResponse {
    /**
     * code : 200
     * msg : success
     * newslist : [{"name":"羽毛球","type":3,"aipre":0,"explain":"干垃圾即其它垃圾,指除可回收物、有害垃圾、厨余垃圾(湿垃圾)以外的其它生活废弃物。","contain":"常见包括砖瓦陶瓷、渣土、卫生间废纸、猫砂、污损塑料、毛发、硬壳、一次性制品、灰土、瓷器碎片等难以回收的废弃物","tip":"尽量沥干水分;难以辨识类别的生活垃圾都可以投入干垃圾容器内"},{"name":"羽毛球拍","type":0,"aipre":0,"explain":"可回收垃圾是指适宜回收、可循环利用的生活废弃物。","contain":"常见包括各类废金属、玻璃瓶、易拉罐、饮料瓶、塑料玩具、书本、报纸、广告单、纸板箱、衣服、床上用品、电子产品等","tip":"轻投轻放;清洁干燥,避免污染,费纸尽量平整;立体包装物请清空内容物,清洁后压扁投放;有尖锐边角的、应包裹后投放"}]
     */
    private int code;
    private String msg;
    private List<NewslistBean> newslist;
    public int getCode() {
        return code;
    }
    public void setCode(int code) {
        this.code = code;
    }
    public String getMsg() {
        return msg;
    }
    public void setMsg(String msg) {
        this.msg = msg;
    }
    public List<NewslistBean> getNewslist() {
        return newslist;
    }
    public void setNewslist(List<NewslistBean> newslist) {
        this.newslist = newslist;
    }
    public static class NewslistBean {
        /**
         * name : 羽毛球
         * type : 3
         * aipre : 0
         * explain : 干垃圾即其它垃圾,指除可回收物、有害垃圾、厨余垃圾(湿垃圾)以外的其它生活废弃物。
         * contain : 常见包括砖瓦陶瓷、渣土、卫生间废纸、猫砂、污损塑料、毛发、硬壳、一次性制品、灰土、瓷器碎片等难以回收的废弃物
         * tip : 尽量沥干水分;难以辨识类别的生活垃圾都可以投入干垃圾容器内
         */
        private String name;
        private int type;
        private int aipre;
        private String explain;
        private String contain;
        private String tip;
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public int getType() {
            return type;
        }
        public void setType(int type) {
            this.type = type;
        }
        public int getAipre() {
            return aipre;
        }
        public void setAipre(int aipre) {
            this.aipre = aipre;
        }
        public String getExplain() {
            return explain;
        }
        public void setExplain(String explain) {
            this.explain = explain;
        }
        public String getContain() {
            return contain;
        }
        public void setContain(String contain) {
            this.contain = contain;
        }
        public String getTip() {
            return tip;
        }
        public void setTip(String tip) {
            this.tip = tip;
        }
    }
}


下面设置api接口,在com.llw.goodtrash包下新建一个api包,包下新建一个ApiService接口。


package com.llw.goodtrash.api;
import com.llw.goodtrash.model.TrashResponse;
import io.reactivex.Observable;
import retrofit2.http.GET;
import retrofit2.http.Query;
import static com.llw.goodtrash.utils.Constant.KEY;
/**
 * API接口
 *
 * @author llw
 * @date 2021/3/30 15:13
 */
public interface ApiService {
    /**
     * 垃圾分类
     * @param word 物品名
     * @return TrashResponse 结果实体
     */
    @GET("/txapi/lajifenlei/index?key=" + KEY)
    Observable<TrashResponse> searchGoods(@Query("word") String word);
}


这里通过Observable观察TrashResponse,当获取到返回数据时,会解析成TrashResponse,就不需要手动去转了,而searchGoods标识方法名,后面的@Query(“word”) String word表示请求API时会把word作为参数拼接到请求地址后面。


下面构建页面访问网络的订阅类


在com.llw.goodtrash包下新建一个contract包,这个包下新建一个MainContract类。


package com.llw.goodtrash.contract;
import android.annotation.SuppressLint;
import com.llw.goodtrash.api.ApiService;
import com.llw.goodtrash.model.TrashResponse;
import com.llw.mvplibrary.base.BasePresenter;
import com.llw.mvplibrary.base.BaseView;
import com.llw.mvplibrary.network.NetworkApi;
import com.llw.mvplibrary.network.observer.BaseObserver;
/**
 * 主页面访问网络
 */
public class MainContract {
    public static class MainPresenter extends BasePresenter<MainView> {
        /**
         * 搜索物品
         *
         * @param word 物品名
         */
        @SuppressLint("CheckResult")
        public void searchGoods(String word) {
            ApiService service = NetworkApi.createService(ApiService.class);
            service.searchGoods(word).compose(NetworkApi.applySchedulers(new BaseObserver<TrashResponse>() {
                @Override
                public void onSuccess(TrashResponse groupResponse) {
                    if (getView() != null) {
                        getView().getSearchResponse(groupResponse);
                    }
                }
                @Override
                public void onFailure(Throwable e) {
                    if (getView() != null) {
                        getView().getSearchResponseFailed(e);
                    }
                }
            }));
        }
    }
    public interface MainView extends BaseView {
        /**
         * 搜索物品返回
         *
         * @param response
         */
        void getSearchResponse(TrashResponse response);
        /**
         * 搜索物品异常返回
         *
         * @param throwable
         */
        void getSearchResponseFailed(Throwable throwable);
    }
}


下面回到MainActivity,先删掉上一篇添加的代码,然后修改代码如下图所示:


20210330174100707.png


之后你需要重写五个方法。


   @Override
    public void initData(Bundle savedInstanceState) {
    }
    @Override
    public int getLayoutId() {
        return 0;
    }
    @Override
    protected MainContract.MainPresenter createPresenter() {
        return null;
    }
    @Override
    public void getSearchResponse(TrashResponse response) {
    }
    @Override
    public void getSearchResponseFailed(Throwable throwable) {
    }


下面会一一修改这五个方法。


四、列表适配器


在上一篇文章中说到返回的是一个可变数组数据,那么是采用列表来显示,有列表,自然要有列表适配器,而列表适配器里面使用了item的布局。在layout下创建item_search_rv.xml,里面的代码如下:


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/item_search_goods"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="@dimen/dp_1"
    android:background="@color/white"
    android:foreground="?attr/selectableItemBackground"
    android:orientation="vertical"
    android:padding="@dimen/dp_12">
    <TextView
        android:id="@+id/tv_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="物品名称"
        android:textColor="@color/black"
        android:textSize="@dimen/sp_16" />
    <TextView
        android:id="@+id/tv_type"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentEnd="true"
        android:text="垃圾类型"
        android:textColor="@color/black"
        android:textSize="@dimen/sp_14" />
    <TextView
        android:id="@+id/tv_explain"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/tv_name"
        android:layout_marginTop="@dimen/dp_8"
        android:text="解释"
        android:textColor="@color/hint_color"
        android:textSize="@dimen/sp_14" />
</RelativeLayout>


然后写适配器,在com.llw.goodtrash包下新建一个adapter包,包下新建一个SearchGoodsAdapter类,代码如下:


package com.llw.goodtrash.adapter;
import android.widget.TextView;
import androidx.annotation.Nullable;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import com.llw.goodtrash.R;
import com.llw.goodtrash.model.TrashResponse;
import java.util.List;
/**
 * 搜索物品结果列表适配器
 */
public class SearchGoodsAdapter extends BaseQuickAdapter<TrashResponse.NewslistBean, BaseViewHolder> {
    public SearchGoodsAdapter(int layoutResId, @Nullable List<TrashResponse.NewslistBean> data) {
        super(layoutResId, data);
    }
    @Override
    protected void convert(BaseViewHolder helper, TrashResponse.NewslistBean item) {
        helper.setText(R.id.tv_name, item.getName())
                .setText(R.id.tv_explain, item.getExplain())
                .addOnClickListener(R.id.item_search_goods);
        TextView tvType = helper.getView(R.id.tv_type);
        switch (item.getType()) {
            case 0:
                tvType.setText("可回收垃圾");
                break;
            case 1:
                tvType.setText("有害垃圾");
                break;
            case 2:
                tvType.setText("厨余垃圾");
                break;
            case 3:
                //干垃圾即其他垃圾
                tvType.setText("干垃圾");
                break;
            default:
                break;
        }
    }
}


五、页面初始化


当我们进入这个页面时要完成页面的初始化,之前是写在onCreate中完成的,现在用initData中完成。而布局id在getLayoutId中返回。


  @Override
    public int getLayoutId() {
        return R.layout.activity_main;
    }


你的onCreate方法可以删掉了,之后创建变量


  private static final String TAG = "MainActivity";
    private EditText etGoods;//输入框
    private ImageView ivClear;//清空输入框
    private RecyclerView rvResult;//结果显示列表
    private List<TrashResponse.NewslistBean> newslistBeanList = new ArrayList<>();//数据列表
    private SearchGoodsAdapter searchGoodsAdapter;//结果列表适配器


然后创建一个initView方法。


  /**
     * 页面初始化
     */
    private void initView() {
        etGoods = findViewById(R.id.et_goods);
        ivClear = findViewById(R.id.iv_clear);
        rvResult = findViewById(R.id.rv_result);
        //配置适配器  设置布局和数据源
        searchGoodsAdapter = new SearchGoodsAdapter(R.layout.item_search_rv, newslistBeanList);
        //设置列表的布局管理器
        rvResult.setLayoutManager(new LinearLayoutManager(this));
        //列表item点击事件
        searchGoodsAdapter.setOnItemChildClickListener((adapter, view, position) -> {
            showMsg("点击了" + newslistBeanList.get(position).getName());
        });
        //设置列表适配器
        rvResult.setAdapter(searchGoodsAdapter);
        //设置输入监听
        etGoods.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }
            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                if (s.toString().length() < 1) {
                    ivClear.setVisibility(View.INVISIBLE);
                } else {
                    ivClear.setVisibility(View.VISIBLE);
                }
            }
            @Override
            public void afterTextChanged(Editable s) {
            }
        });
        //设置动作监听
        etGoods.setOnEditorActionListener((v, actionId, event) -> {
            if (actionId == EditorInfo.IME_ACTION_SEARCH) {
                String word = etGoods.getText().toString().trim();
                if (word.isEmpty()) {
                    showMsg("请输入物品名");
                } else {
                    //显示加载弹窗
                    showLoadingDialog();
                    //控制输入法
                    controlInputMethod();
                    //请求接口
                    mPresenter.searchGoods(word);
                }
                return true;
            }
            return false;
        });
        //清空输入框内容
        ivClear.setOnClickListener(v -> {
            controlInputMethod();
            etGoods.setText("");
        });
    }


这里面有一个方法controlInputMethod,用于控制输入法是否显示,代码如下:


  /**
     * 控制输入法
     * 当输入法打开时关闭,关闭时弹出
     */
    private void controlInputMethod() {
        InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        inputMethodManager.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
    }


别忘记在initData()方法中调用initView();


20210513091527920.png


六、数据显示


返回新的订阅


  @Override
    protected MainContract.MainPresenter createPresenter() {
        return new MainContract.MainPresenter();
    }
  /**
     * 搜索物品返回数据
     *
     * @param response
     */
    @Override
    public void getSearchResponse(TrashResponse response) {
      //隐藏加载弹窗
        hideLoadingDialog();
        if (response.getCode() == Constant.SUCCESS_CODE) {
            //请求成功  进行数据的渲染
            if (response.getNewslist() != null && response.getNewslist().size() > 0) {
                newslistBeanList.clear();
                newslistBeanList.addAll(response.getNewslist());
                //刷新适配器
                searchGoodsAdapter.notifyDataSetChanged();
            } else {
                showMsg("触及到了知识盲区");
            }
        } else {
            //显示请求接口失败的原因
            showMsg(response.getMsg());
        }
    }
    /**
     * 搜索物品失败返回
     *
     * @param throwable 异常信息
     */
    @Override
    public void getSearchResponseFailed(Throwable throwable) {
        hideLoadingDialog();
        Log.e(TAG, throwable.toString());
    }


运行一下:


20210330180734780.gif


OK,就是这样。

相关文章
|
2月前
|
XML Java 数据库
安卓项目:app注册/登录界面设计
本文介绍了如何设计一个Android应用的注册/登录界面,包括布局文件的创建、登录和注册逻辑的实现,以及运行效果的展示。
225 0
安卓项目:app注册/登录界面设计
|
3月前
|
Java 数据库 Android开发
一个Android App最少有几个线程?实现多线程的方式有哪些?
本文介绍了Android多线程编程的重要性及其实现方法,涵盖了基本概念、常见线程类型(如主线程、工作线程)以及多种多线程实现方式(如`Thread`、`HandlerThread`、`Executors`、Kotlin协程等)。通过合理的多线程管理,可大幅提升应用性能和用户体验。
151 15
一个Android App最少有几个线程?实现多线程的方式有哪些?
|
3月前
|
存储 开发工具 Android开发
使用.NET MAUI开发第一个安卓APP
【9月更文挑战第24天】使用.NET MAUI开发首个安卓APP需完成以下步骤:首先,安装Visual Studio 2022并勾选“.NET Multi-platform App UI development”工作负载;接着,安装Android SDK。然后,创建新项目时选择“.NET Multi-platform App (MAUI)”模板,并仅针对Android平台进行配置。了解项目结构,包括`.csproj`配置文件、`Properties`配置文件夹、平台特定代码及共享代码等。
298 2
|
3月前
|
XML Android开发 数据格式
🌐Android国际化与本地化全攻略!让你的App走遍全球无障碍!🌍
在全球化背景下,实现Android应用的国际化与本地化至关重要。本文以一款旅游指南App为例,详细介绍如何通过资源文件拆分与命名、适配布局与方向、处理日期时间及货币格式、考虑文化习俗等步骤,完成多语言支持和本地化调整。通过邀请用户测试并收集反馈,确保应用能无缝融入不同市场,提升用户体验与满意度。
129 3
|
3月前
|
Java 数据库 Android开发
一个Android App最少有几个线程?实现多线程的方式有哪些?
本文介绍了Android应用开发中的多线程编程,涵盖基本概念、常见实现方式及最佳实践。主要内容包括主线程与工作线程的作用、多线程的多种实现方法(如 `Thread`、`HandlerThread`、`Executors` 和 Kotlin 协程),以及如何避免内存泄漏和合理使用线程池。通过有效的多线程管理,可以显著提升应用性能和用户体验。
113 10
|
2月前
|
安全 网络安全 Android开发
深度解析:利用Universal Links与Android App Links实现无缝网页至应用跳转的安全考量
【10月更文挑战第2天】在移动互联网时代,用户经常需要从网页无缝跳转到移动应用中。这种跳转不仅需要提供流畅的用户体验,还要确保安全性。本文将深入探讨如何利用Universal Links(仅限于iOS)和Android App Links技术实现这一目标,并分析其安全性。
391 0
|
3月前
|
XML 数据库 Android开发
10分钟手把手教你用Android手撸一个简易的个人记账App
该文章提供了使用Android Studio从零开始创建一个简单的个人记账应用的详细步骤,包括项目搭建、界面设计、数据库处理及各功能模块的实现方法。
|
4月前
|
API Android开发
Android P 性能优化:创建APP进程白名单,杀死白名单之外的进程
本文介绍了在Android P系统中通过创建应用进程白名单并杀死白名单之外的进程来优化性能的方法,包括设置权限、获取运行中的APP列表、配置白名单以及在应用启动时杀死非白名单进程的代码实现。
76 1
|
4月前
|
Android开发 iOS开发 C#
Xamarin:用C#打造跨平台移动应用的终极利器——从零开始构建你的第一个iOS与Android通用App,体验前所未有的高效与便捷开发之旅
【8月更文挑战第31天】Xamarin 是一个强大的框架,允许开发者使用单一的 C# 代码库构建高性能的原生移动应用,支持 iOS、Android 和 Windows 平台。作为微软的一部分,Xamarin 充分利用了 .NET 框架的强大功能,提供了丰富的 API 和工具集,简化了跨平台移动应用开发。本文通过一个简单的示例应用介绍了如何使用 Xamarin.Forms 快速创建跨平台应用,包括设置开发环境、定义用户界面和实现按钮点击事件处理逻辑。这个示例展示了 Xamarin.Forms 的基本功能,帮助开发者提高开发效率并实现一致的用户体验。
181 0
|
4月前
|
存储 XML Linux
深入理解操作系统:进程管理与调度策略探索安卓应用开发:从零开始构建你的第一个App
【8月更文挑战第28天】在数字世界里航行,操作系统是掌控一切的舵手。本文将带你领略操作系统的精妙设计,特别是进程管理和调度策略这两大核心领域。我们将从基础概念出发,逐步深入到复杂的实现机制,最后通过实际代码示例,揭示操作系统如何高效协调资源,确保多任务顺畅运行的秘密。准备好了吗?让我们启航,探索那些隐藏在日常电脑使用背后的奥秘。 【8月更文挑战第28天】在这个数字时代,拥有一款自己的移动应用程序不仅是技术的展示,也是实现创意和解决问题的一种方式。本文将引导初学者了解安卓开发的基础知识,通过一个简单的待办事项列表App项目,逐步介绍如何利用安卓开发工具和语言来创建、测试并发布一个基本的安卓应用