我的应用程序有一个包含多个项目的listView和一个带有customAdapter的editText。为给定的文本过滤我的项目完全可以,但是当我尝试从已过滤的ist“打开”项目(通过将其传递到新的Intent)时,getItemAtPosition(position)
从列表中返回给定位置的项目。原始列表,但不是来自过滤的列表。如何更改代码以将项目退回到已过滤列表的确切位置?
MainActivity.java
package fasde.android.distanceapp.View;
import android.content.Intent;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.widget.AdapterView;
import android.widget.EditText;
import android.widget.ListView;
import androidx.appcompat.app.AppCompatActivity;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Map;
import java.util.TreeMap;
import fasde.android.distanceapp.Controller.SpielortAdapter;
import fasde.android.distanceapp.DataBase.SaveData;
import fasde.android.distanceapp.Model.Spielort;
import fasde.android.distanceapp.R;
import lombok.NonNull;
/**
* Creates a Activity about a ListView of Spielorts.
*/
public class MainActivity extends AppCompatActivity {
ListView listView;
SpielortAdapter spielortAdapter;
EditText editText;
/**
* Gets the whole app running. Creates a listView, an editText and a spielortAdapter and gets
* all of them running.
*
* @param savedInstanceState
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = getIntent();
@NotNull
String variante = intent.getStringExtra("variante");
listView = findViewById(R.id.list);
editText = findViewById(R.id.inputSearch);
ArrayList<Spielort> spielorts = new ArrayList<>();
Map<String, Spielort> vereine = new TreeMap<>();
vereine.putAll(SaveData.fillVereine(variante));
for (Map.Entry<String, Spielort> entry : vereine.entrySet()) {
spielorts.add(entry.getValue());
}
spielortAdapter = new SpielortAdapter(this, spielorts);
listView.setAdapter(spielortAdapter);
editText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// Nothing
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
MainActivity.this.spielortAdapter.getFilter().filter(s);
}
@Override
public void afterTextChanged(Editable s) {
// Nothing
}
});
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent openDetail = new Intent(MainActivity.this, SpielortDetailActivity.class)
.putExtra("spielort", ((Spielort) listView.getItemAtPosition(position)).toStringArray());
startActivity(openDetail);
}
});
}
}
SpielortAdapter.java
package fasde.android.distanceapp.Controller;
import android.annotation.SuppressLint;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Filter;
import android.widget.TextView;
import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
import fasde.android.distanceapp.Model.Spielort;
import fasde.android.distanceapp.R;
/**
* Custom Adapter for a ListView of Spielorts.
*/
public class SpielortAdapter extends ArrayAdapter<Spielort> {
private Context context;
private List<Spielort> spielortList;
private List<Spielort> filteredList;
private List<Spielort> allDataList;
private SpielortFilter filter;
/**
* Constructor for SpielortAdapter, that creates an instance of this class while giving a
* context and an ArrayList<Spielort>, that is used to initalize two beforehandly declared
* Lists.
*
* @param context
* @param spielortList
*/
public SpielortAdapter(@NonNull Context context, @SuppressLint("SupportAnnotationUsage") @LayoutRes ArrayList<Spielort> spielortList) {
super(context, 0, spielortList);
this.context = context;
this.spielortList = spielortList;
this.allDataList = spielortList;
}
/**
* Returns the size of the spielortList used at the moment.
*
* @return int
*/
@Override
public int getCount() {
return spielortList.size();
}
/**
* Returns an View-element which is used in the ListView. This element contains a Spielort.
*
* @param position
* @param convertView
* @param parent
* @return View
*/
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
View listItem = convertView;
if (listItem == null) {
listItem = LayoutInflater.from(context).inflate(R.layout.list_item, parent, false);
}
Spielort ort = spielortList.get(position);
TextView spielort = listItem.findViewById(R.id.textView_ort);
spielort.setText("\t" + ort.getSpielort());
TextView km = listItem.findViewById(R.id.textView_km);
km.setText(ort.getDistanz() + "km");
TextView kosten = listItem.findViewById(R.id.textView_kosten);
kosten.setText(ort.getKosten().toString() + "€");
TextView kreis = listItem.findViewById(R.id.textView_kreis);
kreis.setText(ort.getKreis().getName());
return listItem;
}
/**
* Returns the current Filter. If it is null, a new one is initialized.
*
* @return Filter
*/
@Override
public Filter getFilter() {
if (filter == null) {
filter = new SpielortFilter();
}
return filter;
}
private class SpielortFilter extends Filter {
/**
* Filters the Spielorts in the spielortList. Every Spielort, which name contains the
* constraint, is returned.
*
* @param constraint
* @return FilterResults
*/
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
filteredList = new ArrayList<>();
for (Spielort ort : allDataList) {
if (ort.getSpielort().toLowerCase().contains(constraint.toString().toLowerCase())) {
filteredList.add(ort);
}
}
results.count = filteredList.size();
results.values = filteredList;
return results;
}
/**
* Publishes the results of the filtering to the listView.
*
* @param constraint
* @param results
*/
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint, @NotNull FilterResults results) {
spielortList = (ArrayList<Spielort>) results.values;
notifyDataSetChanged();
}
}
}
答案 0 :(得分:1)
调用ListView.getItemAtPosition()
方法时,它将调用Adapter.getItem()
方法并返回结果。解决问题的最简单方法是在Adapter.getItem()
类中重载SpielortAdapter
方法,例如波纹管:
@Override
public Spielort getItem(int position) {
return spielortList.get(position);
}
答案 1 :(得分:1)
在SpielortAdapter类中为spielortList创建getter方法并以这种方式使用
//在适配器类中
public List<Spielort> getList(){
return spielortList;
}
//在活动课程中
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent openDetail = new Intent(MainActivity.this, SpielortDetailActivity.class)
.putExtra("spielort", (spielortAdapter .getList().get(position)).toStringArray());
startActivity(openDetail);
}
});
答案 2 :(得分:1)
您应该直接从适配器获得物品。将以下方法添加到您的SpielortAdapter中:
public Model getItemAtPosition(int position)
{
return spielortList.get(position);
}
并从您的OnItemClickListener实现中调用它:
spielortAdapter.getItemAtPosition(position)