package com.example.testapp;
import android.app.Activity;
import android.app.SearchManager;
import android.arch.lifecycle.LifecycleOwner;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.View;
import android.view.animation.AnimationUtils;
import android.view.animation.LayoutAnimationController;
import android.view.inputmethod.InputMethodManager;
import android.widget.SearchView;
import android.widget.TextView;
import com.example.testapp.adapter.ItemAdapter;
import com.example.testapp.model.Item;
import com.firebase.ui.firestore.FirestoreRecyclerOptions;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.Query;
public class DocumentSearchActivity extends AppCompatActivity {
private static final String TAG = DocumentSearchActivity.class.getSimpleName();
private RecyclerView mRecyclerView;
private ItemAdapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
private TextView mNoResultsTextView;
private SearchView mSearchView;
private FirestoreQuery mQuery;
private Toolbar mToolbar;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_document_search);
mToolbar = findViewById(R.id.app_bar);
setSupportActionBar(mToolbar);
getSupportActionBar().setDisplayShowTitleEnabled(false);
mRecyclerView = findViewById(R.id.recycler_view);
mSearchView = findViewById(R.id.search_bar);
mNoResultsTextView = findViewById(R.id.result);
mNoResultsTextView.setVisibility(View.GONE);
if(getIntent().hasExtra(MainActivity.QUERY_EXTRA)){
mSearchView.setQuery(getIntent().getStringExtra(MainActivity.QUERY_EXTRA), true);
mSearchView.requestFocus();
}
mQuery = new FirestoreQuery(this, "");
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
Intent intent = getIntent();
if(Intent.ACTION_SEARCH.equals(intent.getAction())) {
mQuery.setQueryString(intent.getStringExtra(SearchManager.QUERY));
}
mAdapter = new ItemAdapter(mQuery.getOptions());
mRecyclerView.setAdapter(mAdapter);
mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return true;
}
@Override
public boolean onQueryTextChange(String newText) {
mAdapter = new ItemAdapter(mQuery.setQueryString(newText).getOptions());
mRecyclerView.swapAdapter(mAdapter, true);
mAdapter.notifyDataSetChanged();
mAdapter.startListening();
return true;
}
});
}
private void runLayoutAnimation(final RecyclerView recyclerView) {
final Context context = recyclerView.getContext();
final LayoutAnimationController controller =
AnimationUtils.loadLayoutAnimation(context, R.anim.layout_animation_fall_down);
recyclerView.setLayoutAnimation(controller);
recyclerView.getAdapter().notifyDataSetChanged();
recyclerView.scheduleLayoutAnimation();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.actions_document_search_activity, menu);
return super.onCreateOptionsMenu(menu);
}
private class FirestoreQuery {
private LifecycleOwner mLifecycleOwner;
private String mQueryString;
private Query mQuery;
private FirestoreRecyclerOptions<Item> mOptions;
public FirestoreQuery(LifecycleOwner lifecycleOwner, String query) {
mLifecycleOwner = lifecycleOwner;
setQueryString(query);
}
public FirestoreQuery setQueryString(String queryString) {
if(queryString.length() != 0)
this.mQueryString = queryString.substring(0,1).toUpperCase() + queryString.substring(1).toLowerCase();
else
this.mQueryString = queryString;
updateQuery();
updateOptions();
return this;
}
private void updateOptions() {
mOptions = new FirestoreRecyclerOptions.Builder<Item>()
.setQuery(mQuery, Item.class)
.setLifecycleOwner(mLifecycleOwner)
.build();
}
private void updateQuery() {
if(mQueryString.isEmpty()){
this.mQuery = FirebaseFirestore.getInstance()
.collection("tubes_test")
.orderBy("number");
} else {
StringBuilder query_lower = new StringBuilder(mQueryString.length());
query_lower.append(mQueryString);
query_lower.setCharAt(mQueryString.length() - 1, (char) (query_lower.charAt(mQueryString.length() - 1) + 1));
if (mQueryString.matches("^[0-9]{1,3}[A-Z]*$")) {
this.mQuery = FirebaseFirestore.getInstance()
.collection("tubes_test")
.whereGreaterThanOrEqualTo("number", mQueryString)
.whereLessThan("number", query_lower.toString());
} else {
this.mQuery = FirebaseFirestore.getInstance()
.collection("tubes_test")
.whereGreaterThanOrEqualTo("name", mQueryString)
.whereLessThan("name", query_lower.toString());
}
}
}
public FirestoreRecyclerOptions<Item> getOptions() {
return mOptions;
}
}
}
package com.example.testapp.adapter;
import android.content.Context;
import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import com.example.testapp.DocumentViewerActivity;
import com.example.testapp.R;
import com.example.testapp.model.Item;
import com.firebase.ui.firestore.FirestoreRecyclerAdapter;
import com.firebase.ui.firestore.FirestoreRecyclerOptions;
public class ItemAdapter extends FirestoreRecyclerAdapter<Item, ItemAdapter.ItemHolder> {
public ItemAdapter(@NonNull FirestoreRecyclerOptions<Item> options) {
super(options);
}
@Override
protected void onBindViewHolder(@NonNull ItemHolder holder, int position, @NonNull Item item) {
final String tubeNumber = item.getNumber();
holder.mNumberTextView.setText(item.getNumber());
holder.mNameTextView.setText(item.getName());
holder.mFormulaTextView.setText(item.getFormula());
holder.mRangeTextView.setText(item.getRange());
holder.mInfoButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(v.getContext(), DocumentViewerActivity.class);
intent.putExtra("number", tubeNumber);
intent.putExtra("doctype", "info");
v.getContext().startActivity(intent);
}
});
holder.mManualButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(v.getContext(), DocumentViewerActivity.class);
intent.putExtra("number", tubeNumber);
intent.putExtra("doctype", "manual");
v.getContext().startActivity(intent);
}
});
}
@NonNull
@Override
public ItemHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
Context context = viewGroup.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
View tubeView = inflater.inflate(R.layout.item_tube, viewGroup, false);
return new ItemHolder(tubeView);
}
public static class ItemHolder extends RecyclerView.ViewHolder {
public TextView mNumberTextView;
public TextView mNameTextView;
public TextView mFormulaTextView;
public TextView mRangeTextView;
public Button mInfoButton;
public Button mManualButton;
public ItemHolder(View itemView){
super(itemView);
mNumberTextView = itemView.findViewById(R.id.number);
mNameTextView = itemView.findViewById(R.id.name);
mFormulaTextView = itemView.findViewById(R.id.formula);
mRangeTextView = itemView.findViewById(R.id.range);
mInfoButton = itemView.findViewById(R.id.info_btn);
mManualButton = itemView.findViewById(R.id.manual_btn);
}
}
}
以下是对我有效的解决方案。基本上,我创建了一个自定义的可过滤适配器,我只使用Firestore中的数据填充一次。
CustomItemAdapter.java
package com.example.testapp.adapter;
import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.TextView;
import com.example.testapp.DocumentViewerActivity;
import com.example.testapp.R;
import com.example.testapp.model.Item;
import java.util.ArrayList;
import java.util.List;
public class CustomItemAdapter extends RecyclerView.Adapter<CustomItemAdapter.ItemHolder> implements Filterable {
private List<Item> mTubeList;
private List<Item> mTubeListFiltered;
public CustomItemAdapter(List<Item> tubeList){
mTubeList = tubeList;
mTubeListFiltered = tubeList;
}
@NonNull
@Override
public ItemHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
View tubeView = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.item_tube, viewGroup, false);
return new ItemHolder(tubeView);
}
@Override
public void onBindViewHolder(@NonNull ItemHolder holder, int i) {
final Item item = mTubeListFiltered.get(i);
//Setting up view
}
@Override
public int getItemCount() {
return mTubeListFiltered.size();
}
@Override
public Filter getFilter() {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
String pattern = constraint.toString().toLowerCase();
if(pattern.isEmpty()){
mTubeListFiltered = mTubeList;
} else {
List<Item> filteredList = new ArrayList<>();
for(Item tube: mTubeList){
if(tube.getNumber().toLowerCase().contains(pattern) || tube.getName().toLowerCase().contains(pattern)) {
filteredList.add(tube);
}
}
mTubeListFiltered = filteredList;
}
FilterResults filterResults = new FilterResults();
filterResults.values = mTubeListFiltered;
return filterResults;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
mTubeListFiltered = (ArrayList<Item>) results.values;
notifyDataSetChanged();
}
};
}
public static class ItemHolder extends RecyclerView.ViewHolder {
//ViewHolder's code
}
}
活动中的片段:
Query query = FirebaseFirestore.getInstance()
.collection("test")
.orderBy("number");
query.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task) {
mAdapter = new CustomItemAdapter(task.getResult().toObjects(Item.class));
mRecyclerView.setAdapter(mAdapter);
}
});
mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return true;
}
@Override
public boolean onQueryTextChange(String newText) {
mAdapter.getFilter().filter(newText);
return true;
}
});
如何使用ajax/json填充包含“选择”过滤器的ng表? Plunk显示问题:http://plnkr.co/Zn09LV 我正在努力掌握AngualrJS和ng表扩展,虽然我可以得到一些带有工作过滤器的好表,例如当我使用javascript中定义的静态数据时——一旦我尝试将真实数据加载到表中,我就遇到了一个障碍。 ng表的主体填充正确,只要我只使用文本过滤器,一切似乎都正常: 很好用。 但是,
我有一个页眉和页脚(),中间有一个。
我是Android开发的新手。目前,我正在使用Firestore UI填充RecycerView。它可以正常工作,但现在我希望在RecycerView不包含数据或插入某些内容时动态隐藏/显示该视图。在我的适配器类中重写onDataChanged方法时,我注意到我可以正确地动态检测适配器中的项数是否为0。我如何使用它使我的RecycerView可见或不可见?
你知道我如何使用FireStore填充文档上的引用字段吗?
问题内容: 这是我文件中的自定义用户身份验证设置,但是我目前正在通过该方法手动提供用户;是否可以从Redis服务器获取值? 例如,如果用户存在并且密码可以,可以自动填写这些详细信息吗? 问题答案: 是的,您可以针对Redis数据源进行身份验证。您可以使用内置代替,或者如果您要使用现有的Redis数据集而不是内置模式,则我提供了一个解决方案,您可以扩展。第一种方法最简单: 使用: 因此,您需要建立与
作为我作业的一部分,我们得到了一个我们不能更改的接口,以及一些用来开发我们方法的预定义测试。 界面如下: 我正在运行的特定测试: 以及我需要从测试中创建的方法: 从测试中我可以看出,在方法中,我需要创建并用注册映射中匹配的学生填充它,然后返回列表。 我创建了以下字段:- 我搞不懂的是,如何将注册地图中的数据传递到学生列表中,以使测试中的断言为真。