我想显示一个标题复选框列表(本例中为行星),当我点击其中一个复选框(此示例中的Toast和Log)时会发生一些事情。但是要显示复选框,我需要使用自定义适配器(当我使用SimpleAdapter时一切正常),但OnItemClickListener不再有效。复选框选中/取消选中,但我无法让DialogFragment确认已点击任何内容。
还有一个搜索栏,可以在您键入时动态过滤列表,但我认为这不会产生影响,因为它与SimpleAdapter一起正常工作。
这是一些有趣的代码:
MainActivity.java
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentActivity;
public class MainActivity extends FragmentActivity
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DialogFragment fragment = SearchDialogFragment.newInstance();
fragment.show(getSupportFragmentManager(), "SearchDialog");
}
}
SearchDialogFragment.java
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.SearchView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class SearchDialogFragment extends DialogFragment
{
private List<Map<String, Boolean>> planetsList;
private ListView listView;
private List<String> selectedPlanets;
public static SearchDialogFragment newInstance()
{
return new SearchDialogFragment();
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState)
{
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
LayoutInflater inflater = getActivity().getLayoutInflater();
View view = inflater.inflate(R.layout.fragment_search_dialog, null);
builder.setTitle("List of planets");
builder.setView(view);
listView = (ListView) view.findViewById(R.id.fragment_list_view);
selectedPlanets = new ArrayList<>();
createPlanetsList("");
resetAdapter();
/**
* NOT WORKING
*/
listView.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
public void onItemClick(AdapterView<?> parentAdapter, View view, int position, long id)
{
Toast.makeText(getActivity(), "CLICK!!!!", Toast.LENGTH_SHORT).show();
Log.e("SDF", "CLICK!!!!");
}
});
/**
* /NOT WORKING
*/
SearchView search = (SearchView) view.findViewById(R.id.fragment_search_view);
search.setQueryHint("Search list");
// Reacts to the search bar
search.setOnQueryTextListener(new SearchView.OnQueryTextListener()
{
@Override
public boolean onQueryTextSubmit(String query)
{
return false;
}
@Override
public boolean onQueryTextChange(String searchText)
{
updateDisplayList(searchText);
return false;
}
});
return builder.create();
}
@Override
public void onAttach(Activity activity)
{
super.onAttach(activity);
}
@Override
public void onDetach()
{
super.onDetach();
}
private void createPlanetsList(String searchText)
{
planetsList = new ArrayList<>();
addPlanet("Mercury", searchText);
addPlanet("Venus", searchText);
addPlanet("Earth", searchText);
addPlanet("Mars", searchText);
addPlanet("Jupiter", searchText);
addPlanet("Saturn", searchText);
addPlanet("Uranus", searchText);
addPlanet("Neptune", searchText);
}
private void addPlanet(String planetName, String searchText)
{
if (planetName.toLowerCase().contains(searchText.toLowerCase()))
{
HashMap<String, Boolean> planet = new HashMap<>(1);
boolean isSelected = selectedPlanets.contains(planetName);
planet.put(planetName, isSelected);
planetsList.add(planet);
}
}
private void resetAdapter()
{
// It worked when I used this instead of my custom adapter
/*
SimpleAdapter simpleAdapter = new SimpleAdapter(
getActivity(), // Context
planetsList, // Data list
android.R.layout.select_dialog_multichoice, // Row layout
new String[] {"planet"}, // Keys for list
new int[] {android.R.id.text1}); // View ID used to show the data
listView.setAdapter(simpleAdapter);
*/
MultiSelectAdapter adapter = MultiSelectAdapter.getAdapter(getActivity(), planetsList, selectedPlanets);
listView.setAdapter(adapter);
}
private void updateDisplayList(String searchText)
{
createPlanetsList(searchText);
resetAdapter();
}
}
MultiSelectAdapter.java
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import java.util.List;
import java.util.Map;
public class MultiSelectAdapter extends ArrayAdapter
{
private Context context;
private List<Map<String, Boolean>> planetsList;
private static List<String> selectedPlanets;
public static MultiSelectAdapter getAdapter(Context context, List<Map<String, Boolean>> objects, List<String> dialogSelectedPlanets)
{
selectedPlanets = dialogSelectedPlanets;
return new MultiSelectAdapter(context, android.R.id.text1, objects);
}
private MultiSelectAdapter(Context context, int resource, List<Map<String, Boolean>> objects)
{
super(context, resource, objects);
this.context = context;
this.planetsList = objects;
}
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.fragment_row_layout, parent, false);
CheckBox checkBox = (CheckBox) rowView.findViewById(R.id.row_check_box);
String planetName = (String) planetsList.get(position).keySet().toArray()[0];
checkBox.setText(planetName);
if (selectedPlanets.contains(planetName))
{
checkBox.setChecked(true);
}
return rowView;
}
}
fragment_search_dialog.xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:context="lomax.mysearchinterface.SearchDialogFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<SearchView
android:id="@+id/fragment_search_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="30dp"
android:layout_marginRight="30dp"
android:iconifiedByDefault="false"/>
<ListView
android:id="@+id/fragment_list_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
</LinearLayout>
fragment_row_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<CheckBox
android:id="@+id/row_check_box"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textAllCaps="true"
android:text="Planet name"
android:focusable="false"/>
</LinearLayout>
答案 0 :(得分:0)
经过互联网争取一些想法后,我偶然发现了解决这个问题的方法。在我的适配器类的getView(...)方法中:
checkBox.setOnCheckedChangeListener(this);
并让我的适配器类实现:
implement CompoundButton.OnCheckedChangeListener
这似乎有效,无需更改行布局的XML或任何其他聪明。
希望这有助于下一个遇到这个问题的可怜的人......