parent
8ce7134a04
commit
4b0b118828
@ -0,0 +1,48 @@ |
||||
package com.community.pocket.data.adapter; |
||||
|
||||
import android.content.Context; |
||||
import android.widget.ArrayAdapter; |
||||
|
||||
import com.community.pocket.data.model.GarbageSorting; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.HashMap; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
|
||||
public class GarbageAdpter extends ArrayAdapter<String> { |
||||
|
||||
private List<GarbageSorting> dataList; |
||||
private List<String> list = new ArrayList<>(); |
||||
private Map<String, GarbageSorting> map = new HashMap<>(); |
||||
|
||||
|
||||
public GarbageAdpter(List<GarbageSorting> dataList, Context context) { |
||||
super(context, android.R.layout.simple_list_item_1); |
||||
addAll(dataList); |
||||
} |
||||
|
||||
public void addAll(List<GarbageSorting> dataList) { |
||||
this.dataList = dataList; |
||||
this.list.clear(); |
||||
this.map.clear(); |
||||
for (GarbageSorting garbageSorting : dataList) { |
||||
this.list.add(garbageSorting.getName()); |
||||
this.map.put(garbageSorting.getName(), garbageSorting); |
||||
} |
||||
clear(); |
||||
addAll(this.list); |
||||
} |
||||
|
||||
public GarbageSorting get(String name) { |
||||
return this.map.get(name); |
||||
} |
||||
|
||||
public boolean containsKey(String name) { |
||||
return this.list.contains(name); |
||||
} |
||||
|
||||
public List<String> getList() { |
||||
return list; |
||||
} |
||||
} |
@ -0,0 +1,42 @@ |
||||
package com.community.pocket.data.main.garbage; |
||||
|
||||
|
||||
import com.community.pocket.R; |
||||
import com.community.pocket.data.model.GarbageSorting; |
||||
import com.community.pocket.ui.main.ui.garbage.GarbageSortingResponse; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* 垃圾分类请求接口 |
||||
* TODO 完善逻辑 |
||||
*/ |
||||
public class GarbageSortingRequest { |
||||
private static volatile GarbageSortingRequest instance; |
||||
|
||||
private GarbageSortingRequest() { |
||||
} |
||||
|
||||
public static GarbageSortingRequest getInstance() { |
||||
if (instance == null) { |
||||
instance = new GarbageSortingRequest(); |
||||
} |
||||
return instance; |
||||
} |
||||
|
||||
//检索垃圾
|
||||
public GarbageSortingResponse search() { |
||||
List<GarbageSorting> garbageSortings = new ArrayList<>(); |
||||
for (int i = 0; i < 10; i++) { |
||||
GarbageSorting garbageSorting = new GarbageSorting(); |
||||
garbageSorting.setName("test" + i); |
||||
garbageSorting.setSorting("有害垃圾"); |
||||
garbageSortings.add(garbageSorting); |
||||
} |
||||
GarbageSortingResponse garbageSortingResponse = new GarbageSortingResponse(); |
||||
garbageSortingResponse.setSuccess(R.string.garbage_search_ok); |
||||
garbageSortingResponse.setBody(garbageSortings); |
||||
return garbageSortingResponse; |
||||
} |
||||
} |
@ -0,0 +1,35 @@ |
||||
package com.community.pocket.data.model; |
||||
|
||||
//垃圾分类信息
|
||||
public class GarbageSorting { |
||||
//名称
|
||||
private String name; |
||||
//分类
|
||||
private String sorting; |
||||
//垃圾图片
|
||||
private String image; |
||||
|
||||
public String getName() { |
||||
return name; |
||||
} |
||||
|
||||
public void setName(String name) { |
||||
this.name = name; |
||||
} |
||||
|
||||
public String getSorting() { |
||||
return sorting; |
||||
} |
||||
|
||||
public void setSorting(String sorting) { |
||||
this.sorting = sorting; |
||||
} |
||||
|
||||
public String getImage() { |
||||
return image; |
||||
} |
||||
|
||||
public void setImage(String image) { |
||||
this.image = image; |
||||
} |
||||
} |
@ -1,16 +1,42 @@ |
||||
package com.community.pocket.ui.main.ui.garbage; |
||||
|
||||
import android.os.Build; |
||||
import android.view.View; |
||||
|
||||
import androidx.annotation.RequiresApi; |
||||
|
||||
import com.community.pocket.R; |
||||
import com.community.pocket.ui.main.TestMainFragment; |
||||
import com.community.pocket.ui.main.MainFragment; |
||||
|
||||
import org.xutils.view.annotation.ContentView; |
||||
import org.xutils.view.annotation.Event; |
||||
|
||||
|
||||
@ContentView(R.layout.garbage) |
||||
public class GarbageFragment extends MainFragment { |
||||
@Override |
||||
protected int fragmentId() { |
||||
return R.id.grabage_fragment; |
||||
} |
||||
|
||||
//跳转到垃圾分类界面
|
||||
@RequiresApi(api = Build.VERSION_CODES.KITKAT) |
||||
@Event(value = R.id.garbage_sorting) |
||||
private void sorting(View view) { |
||||
ctrl().navigate(R.id.garbageSortingFragment); |
||||
changeColor(view); |
||||
} |
||||
|
||||
@ContentView(R.layout.fragment_notifications) |
||||
public class GarbageFragment extends TestMainFragment { |
||||
//跳转到废品回收界面
|
||||
@RequiresApi(api = Build.VERSION_CODES.KITKAT) |
||||
@Event(value = R.id.garbage_waste) |
||||
private void waste(View view) { |
||||
ctrl().navigate(R.id.garbageWasteFragment); |
||||
changeColor(view); |
||||
} |
||||
|
||||
@Override |
||||
protected int viewId() { |
||||
return R.id.text_notifications; |
||||
protected int[] button_ids() { |
||||
return new int[]{R.id.garbage_sorting, R.id.garbage_waste}; |
||||
} |
||||
} |
||||
|
@ -0,0 +1,116 @@ |
||||
package com.community.pocket.ui.main.ui.garbage; |
||||
|
||||
import android.os.Bundle; |
||||
import android.text.Editable; |
||||
import android.view.View; |
||||
import android.widget.AutoCompleteTextView; |
||||
import android.widget.ImageView; |
||||
import android.widget.TextView; |
||||
import android.widget.Toast; |
||||
|
||||
import androidx.annotation.NonNull; |
||||
import androidx.annotation.Nullable; |
||||
import androidx.lifecycle.Observer; |
||||
import androidx.lifecycle.ViewModelProvider; |
||||
|
||||
import com.community.pocket.R; |
||||
import com.community.pocket.data.adapter.GarbageAdpter; |
||||
import com.community.pocket.data.model.GarbageSorting; |
||||
import com.community.pocket.ui.BaseFragment; |
||||
import com.community.pocket.ui.listener.MyTextChange; |
||||
import com.community.pocket.ui.main.ui.share.MyAutoCompleteTextView; |
||||
|
||||
import org.xutils.view.annotation.ContentView; |
||||
import org.xutils.view.annotation.ViewInject; |
||||
|
||||
import java.util.List; |
||||
|
||||
@ContentView(R.layout.garbage_sorting) |
||||
public class GarbageSortingFragment extends BaseFragment { |
||||
|
||||
@ViewInject(R.id.search_sorting) |
||||
private AutoCompleteTextView searchSorting; |
||||
|
||||
//垃圾名
|
||||
@ViewInject(R.id.name) |
||||
private TextView name; |
||||
|
||||
//垃圾分类
|
||||
@ViewInject(R.id.sorting) |
||||
private TextView sorting; |
||||
|
||||
//垃圾图片
|
||||
@ViewInject(R.id.image) |
||||
private ImageView image; |
||||
|
||||
private MyAutoCompleteTextView myAutoCompleteTextView; |
||||
|
||||
private GarbageAdpter garbageAdpter; |
||||
|
||||
@Override |
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { |
||||
super.onViewCreated(view, savedInstanceState); |
||||
|
||||
GarbageSortingViewModel viewModel = new ViewModelProvider(this, new ViewModelProvider.NewInstanceFactory()).get(GarbageSortingViewModel.class); |
||||
|
||||
myAutoCompleteTextView = new MyAutoCompleteTextView(searchSorting, viewModel); |
||||
|
||||
//监听垃圾分类检索状态
|
||||
viewModel.getGarbageSortingResponse().observe(getViewLifecycleOwner(), new Observer<GarbageSortingResponse>() { |
||||
@Override |
||||
public void onChanged(GarbageSortingResponse garbageSortingResponse) { |
||||
if (garbageSortingResponse == null) { |
||||
return; |
||||
} |
||||
|
||||
if (garbageSortingResponse.getSuccess() != null) { |
||||
initSearch(garbageSortingResponse.getBody()); |
||||
} |
||||
|
||||
if (garbageSortingResponse.getError() != null) { |
||||
Toast.makeText(getContext(), garbageSortingResponse.ok(getContext()), Toast.LENGTH_SHORT).show(); |
||||
} |
||||
} |
||||
}); |
||||
|
||||
//添加监听触发搜索
|
||||
searchSorting.addTextChangedListener(new MyTextChange() { |
||||
@Override |
||||
public void afterTextChanged(Editable s) { |
||||
if (garbageAdpter != null && garbageAdpter.containsKey(s.toString())) { |
||||
initView(garbageAdpter.get(s.toString())); |
||||
} |
||||
|
||||
myAutoCompleteTextView.searchHandler(); |
||||
} |
||||
}); |
||||
|
||||
} |
||||
|
||||
/** |
||||
* 初始化垃圾分类信息 |
||||
* |
||||
* @param garbageSorting 垃圾分类 |
||||
*/ |
||||
private void initView(GarbageSorting garbageSorting) { |
||||
name.setText(garbageSorting.getName()); |
||||
sorting.setText(garbageSorting.getSorting()); |
||||
} |
||||
|
||||
/** |
||||
* 检索垃圾信息 |
||||
* |
||||
* @param garbageSortings 垃圾分类信息 |
||||
*/ |
||||
private void initSearch(List<GarbageSorting> garbageSortings) { |
||||
// 设置适配器
|
||||
if (garbageAdpter == null) { |
||||
garbageAdpter = new GarbageAdpter(garbageSortings, getContext()); |
||||
// 将适配器与当前AutoCompleteTextView控件绑定
|
||||
searchSorting.setAdapter(garbageAdpter); |
||||
} else { |
||||
garbageAdpter.addAll(garbageSortings); |
||||
} |
||||
myAutoCompleteTextView.refreshDropList(); |
||||
} |
||||
} |
@ -0,0 +1,9 @@ |
||||
package com.community.pocket.ui.main.ui.garbage; |
||||
|
||||
import com.community.pocket.data.model.GarbageSorting; |
||||
import com.community.pocket.ui.main.ui.share.Response; |
||||
|
||||
import java.util.List; |
||||
|
||||
public class GarbageSortingResponse extends Response<List<GarbageSorting>> { |
||||
} |
@ -0,0 +1,31 @@ |
||||
package com.community.pocket.ui.main.ui.garbage; |
||||
|
||||
import androidx.lifecycle.MutableLiveData; |
||||
|
||||
import com.community.pocket.data.main.garbage.GarbageSortingRequest; |
||||
import com.community.pocket.ui.main.ui.share.BaseViewModel; |
||||
import com.community.pocket.ui.main.ui.share.SearchViewModel; |
||||
|
||||
/** |
||||
* 垃圾分类数据管理 |
||||
*/ |
||||
public class GarbageSortingViewModel extends BaseViewModel<GarbageSortingRequest> implements SearchViewModel { |
||||
|
||||
//垃圾分类信息请求状态
|
||||
private MutableLiveData<GarbageSortingResponse> garbageSortingResponse = new MutableLiveData<>(); |
||||
|
||||
MutableLiveData<GarbageSortingResponse> getGarbageSortingResponse() { |
||||
return garbageSortingResponse; |
||||
} |
||||
|
||||
@Override |
||||
protected GarbageSortingRequest getRequest() { |
||||
return GarbageSortingRequest.getInstance(); |
||||
} |
||||
|
||||
@Override |
||||
public void search(String content) { |
||||
GarbageSortingResponse response = getRequest().search(); |
||||
garbageSortingResponse.setValue(response); |
||||
} |
||||
} |
@ -0,0 +1,10 @@ |
||||
package com.community.pocket.ui.main.ui.garbage; |
||||
|
||||
import com.community.pocket.R; |
||||
import com.community.pocket.ui.BaseFragment; |
||||
|
||||
import org.xutils.view.annotation.ContentView; |
||||
|
||||
@ContentView(R.layout.garbage_waste) |
||||
public class GarbageWasteFragment extends BaseFragment { |
||||
} |
@ -0,0 +1,79 @@ |
||||
package com.community.pocket.ui.main.ui.share; |
||||
|
||||
import android.annotation.SuppressLint; |
||||
import android.os.Handler; |
||||
import android.os.Looper; |
||||
import android.os.Message; |
||||
import android.util.Log; |
||||
import android.widget.AutoCompleteTextView; |
||||
|
||||
import org.jetbrains.annotations.NotNull; |
||||
|
||||
import java.lang.reflect.Method; |
||||
|
||||
/** |
||||
* 动态更新自动搜索框数据 |
||||
*/ |
||||
public class MyAutoCompleteTextView { |
||||
//AutoCompleteTextView的doBeforeTextChanged方法
|
||||
private Method doBeforeTextChanged; |
||||
//AutoCompleteTextView的doAfterTextChanged方法
|
||||
private Method doAfterTextChanged; |
||||
|
||||
private AutoCompleteTextView view; |
||||
|
||||
private SearchViewModel searchViewModel; |
||||
|
||||
public MyAutoCompleteTextView(AutoCompleteTextView view, SearchViewModel searchViewModel) { |
||||
this.view = view; |
||||
this.searchViewModel = searchViewModel; |
||||
} |
||||
|
||||
//延时搜索的handler
|
||||
private Handler searchHandler = new Handler(Looper.getMainLooper()) { |
||||
public void handleMessage(@NotNull Message msg) { |
||||
dealSearchHint(); |
||||
} |
||||
}; |
||||
|
||||
|
||||
/** |
||||
* 根据用户输入的字符去调用接口查询 |
||||
*/ |
||||
private void dealSearchHint() { |
||||
String searchContent = view.getText().toString(); |
||||
if (searchContent.isEmpty()) { |
||||
return; |
||||
} |
||||
// appointmentViewModel.searchPeople(searchContent);
|
||||
searchViewModel.search(searchContent); |
||||
} |
||||
|
||||
@SuppressLint("SoonBlockedPrivateApi") |
||||
public void refreshDropList() { |
||||
try { |
||||
if (doAfterTextChanged == null) { |
||||
Class<AutoCompleteTextView> autoCompleteTextView = AutoCompleteTextView.class; |
||||
doBeforeTextChanged = autoCompleteTextView.getDeclaredMethod("doBeforeTextChanged"); |
||||
doBeforeTextChanged.setAccessible(true); |
||||
doAfterTextChanged = autoCompleteTextView.getDeclaredMethod("doAfterTextChanged"); |
||||
doAfterTextChanged.setAccessible(true); |
||||
} |
||||
|
||||
// doBeforeTextChanged.invoke(appointment);
|
||||
doAfterTextChanged.invoke(view); |
||||
} catch (Exception e) { |
||||
Log.e("", e.toString()); |
||||
} |
||||
} |
||||
|
||||
public void searchHandler() { |
||||
long time = System.currentTimeMillis(); |
||||
//输入的字符间隔时间 小于700毫秒 移除以前的handler 延时600毫秒执行
|
||||
if (view.getTag() != null && time - (Long) view.getTag() < 700) { |
||||
searchHandler.removeMessages(1); |
||||
} |
||||
searchHandler.sendEmptyMessageDelayed(1, 600); |
||||
view.setTag(time); |
||||
} |
||||
} |
@ -0,0 +1,9 @@ |
||||
package com.community.pocket.ui.main.ui.share; |
||||
|
||||
/** |
||||
* 搜索框请求数据源 |
||||
*/ |
||||
public interface SearchViewModel { |
||||
//请求方法
|
||||
void search(String content); |
||||
} |
@ -0,0 +1,45 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||
xmlns:app="http://schemas.android.com/apk/res-auto" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_gravity="center_vertical"> |
||||
|
||||
<AutoCompleteTextView |
||||
android:id="@+id/search_sorting" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:completionThreshold="1" |
||||
android:hint="@string/prompt_garbage_name" |
||||
app:layout_constraintStart_toStartOf="parent" |
||||
app:layout_constraintTop_toTopOf="parent" /> |
||||
|
||||
<TextView |
||||
android:id="@+id/name" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginTop="8dp" |
||||
android:gravity="center" |
||||
android:textSize="24sp" |
||||
app:layout_constraintStart_toStartOf="parent" |
||||
app:layout_constraintTop_toBottomOf="@id/search_sorting" /> |
||||
|
||||
<TextView |
||||
android:id="@+id/sorting" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginTop="8dp" |
||||
android:gravity="center" |
||||
android:textSize="24sp" |
||||
app:layout_constraintStart_toStartOf="parent" |
||||
app:layout_constraintTop_toBottomOf="@id/name" /> |
||||
|
||||
<ImageView |
||||
android:id="@+id/image" |
||||
android:layout_width="@dimen/size_200" |
||||
android:layout_height="@dimen/size_200" |
||||
android:contentDescription="@string/garbage_img" |
||||
app:layout_constraintEnd_toEndOf="parent" |
||||
app:layout_constraintStart_toStartOf="parent" |
||||
app:layout_constraintTop_toBottomOf="@id/sorting" /> |
||||
</androidx.constraintlayout.widget.ConstraintLayout> |
@ -0,0 +1,31 @@ |
||||
<?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" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content"> |
||||
|
||||
<Button |
||||
android:id="@+id/garbage_sorting" |
||||
style="?android:attr/buttonBarStyle" |
||||
android:layout_width="0dp" |
||||
android:layout_height="wrap_content" |
||||
android:layout_weight="1" |
||||
android:background="@color/colorAccent" |
||||
android:text="@string/garbage_sorting" |
||||
app:layout_constraintBottom_toBottomOf="parent" |
||||
app:layout_constraintStart_toStartOf="parent" |
||||
app:layout_constraintTop_toTopOf="parent" /> |
||||
|
||||
<Button |
||||
android:id="@+id/garbage_waste" |
||||
style="?android:attr/buttonBarStyle" |
||||
android:layout_width="0dp" |
||||
android:layout_height="wrap_content" |
||||
android:layout_weight="1" |
||||
android:background="@color/button_unchecked" |
||||
android:text="@string/garbage_waste" |
||||
app:layout_constraintBottom_toBottomOf="parent" |
||||
app:layout_constraintStart_toEndOf="@id/forum_hot" |
||||
app:layout_constraintTop_toTopOf="parent" /> |
||||
|
||||
</LinearLayout> |
@ -0,0 +1,4 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent" /> |
@ -0,0 +1,15 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<navigation xmlns:android="http://schemas.android.com/apk/res/android" |
||||
xmlns:app="http://schemas.android.com/apk/res-auto" |
||||
android:id="@+id/garbage_navigation" |
||||
app:startDestination="@id/garbageSortingFragment"> |
||||
|
||||
<fragment |
||||
android:id="@+id/garbageSortingFragment" |
||||
android:name="com.community.pocket.ui.main.ui.garbage.GarbageSortingFragment" |
||||
android:label="GarbageSortingFragment" /> |
||||
<fragment |
||||
android:id="@+id/garbageWasteFragment" |
||||
android:name="com.community.pocket.ui.main.ui.garbage.GarbageWasteFragment" |
||||
android:label="GarbageWasteFragment" /> |
||||
</navigation> |
Loading…
Reference in new issue