如何从 SimpleCursorAdapter 的子类中操作我的 Android 片段?
How can I manipulate my Android fragment from within a subclass of SimpleCursorAdapter?
我的应用程序使用与 ViewPager 关联的 Fragments 来创建选项卡。
在一个选项卡上,我使用 ListView 在 table 中显示我的数据库的内容。我扩展了 SimpleCursorAdapter 以便在我的列表的每一行上执行一些自定义任务(例如,交替行颜色、按钮等)。有一次,我想单击一行中的一个图标并让它切换选项卡,但我在从我的 CustomSimpleCursorAdapter class 中访问 FragmentManager 和 ViewPager 时遇到问题。我可以在片段本身中执行此操作(请参阅注释掉的部分),但是当我切换到使用 CustomSimpleCursorAdapter 时,我失去了这种能力。
那么,如何从我的自定义 class 中访问我的 FragmentManager 和 ViewPager?
注意: 我已经在 CustomSimpleCursorAdapter.java 中标记了我遇到问题的位置
// THIS IS WHERE I AM HAVING ISSUES WITH:
Home.java
package myPackage;
public class Home extends Fragment {
private View rootView;
private CustomSimpleCursorAdapter mySimpleCursorAdapter;
private ViewPager myViewPager;
private SwipeRefreshLayout studentSwipeRefresh;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
rootView = inflater.inflate(R.layout.home, container, false);
myViewPager = (ViewPager) getActivity().findViewById(R.id.pager);
studentSwipeRefresh = (SwipeRefreshLayout) rootView.findViewById(R.id.student_swipe_refresh);
return rootView;
}
@Override
public void onViewCreated(View rootView, Bundle savedInstanceState) {
super.onViewCreated(rootView, savedInstanceState);
drawTheStudentView();
studentSwipeRefresh.setColorSchemeColors(Color.parseColor(Constants.RED), Color.parseColor(Constants.ORANGE), Color.parseColor(Constants.YELLOW), Color.parseColor(Constants.GREEN), Color.parseColor(Constants.BLUE), Color.parseColor(Constants.INDIGO), Color.parseColor(Constants.VIOLET));
studentSwipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
studentSwipeRefresh.setRefreshing(false);
drawTheStudentView();
}
});
}
private void drawTheStudentView(){
DatabaseHelper myDBHelper = new DatabaseHelper(getActivity());
Cursor studentCursor = myDBHelper.getStudentsCursor();
String[] fromColumns = {"_id","studentID","location"};
int[] toViews = {R.id.student_number_textview, R.id.student_id_textview, R.id.student_location.textview};
mySimpleCursorAdapter = new CustomSimpleCursorAdapter(getActivity(), R.layout.student_layout, studentCursor, fromColumns, toViews, 0);
// Replace the _id column with a student count
mySimpleCursorAdapter.setViewBinder(new SimpleCursorAdapter.ViewBinder() {
@Override
public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
String counter = Integer.toString((cursor.getPosition()+1));
TextView modifiedTextView = (TextView) view;
if(columnIndex == 0){
modifiedTextView.setText(counter);
return true;
}
return false;
}
});
ListView myListView = (ListView) rootView.findViewById(R.id.student_row);
// I COMMENTED THIS OUT. THIS WORKS FOR CLICKING THE ENTIRE ROW AND HAVING AN ACTION PERFORMED.
// Listen for somebody clicking on a Student ID, and process
// myListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
// @Override
// public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// Cursor subCursor = (Cursor) mySimpleCursorAdapter.getItem(position);
// String studentIDNumber = subCursor.getString(subCursor.getColumnIndex("studentID"));
//
// StudentInformation studentInformation = (StudentInformation) getFragmentManager().findFragmentByTag(getFragmentTag(Constants.TAB_INDEX_PATIENT_VITALS));
// studentInformation.setStudendIDNumber(studentIDNumber);
//
// myViewPager.setCurrentItem(Constants.TAB_INDEX_STUDENT_LOCATION);
// }
// });
// Draw the list
myListView.setAdapter(mySimpleCursorAdapter);
myDBHelper.close();
}
// Pass me a tab index (see Constants.java) and I'll return a refrence to that tab.
private String getFragmentTag(int tagID){
return "android:switcher:" + R.id.pager + ":" + tagID;
}
}
CustomSimpleCursorAdapter.java
package myPackage;
public class CustomSimpleCursorAdapter extends SimpleCursorAdapter {
private Context context;
private Cursor cursor;
public CustomSimpleCursorAdapter(Context context, int layout, Cursor cursor, String[] from, int[] to, int flags) {
super(context, layout, cursor, from, to, flags);
this.context = context;
this.cursor = cursor;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent){
// Alternate the color of the data rows.
View row = super.getView(position, convertView, parent);
if(position % 2 == 0){
row.setBackgroundColor(Color.parseColor(Constants.WHITE));
} else {
row.setBackgroundColor(Color.parseColor(Constants.LIGHTGREY));
}
// If the "Information" icon/button is clicked, set the information and switch to that tab/fragment.
ImageView statusButton = (ImageView)row.findViewById(R.id.student_status_button);
statusButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View myView) {
cursor.moveToPosition(position);
String studentID = cursor.getString(1);
Toast statusToast = Toast.makeText(context, "Showing information for student " + studentID, Toast.LENGTH_SHORT);
statusToast.show();
// THIS IS WHERE I AM HAVING ISSUES WITH:
// * getFragmentManager()
// * myViewPager.setCurrentItem()
StudentInformation studentInformation = (StudentInformation) getFragmentManager().findFragmentByTag(getFragmentTag(Constants.TAB_INDEX_STUDENT_INFORMATION));
studentInformation.setStudentNumber(studentID);
myViewPager.setCurrentItem(Constants.TAB_INDEX_STUDENT_INFORMATION);
}
});
// If the "Location" button is clicked, then show a Toast with the information.
ImageView locationButton = (ImageView)row.findViewById(R.id.student_location_button);
locationButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View myView) {
cursor.moveToPosition(position);
String studentID = cursor.getString(1);
Toast statusToast = Toast.makeText(context, "Sending location for student " + studentID + " to MESA", Toast.LENGTH_LONG);
statusToast.show();
}
});
return row;
}
// Pass me a tab index (see Constants.java) and I'll return a refrence to that tab.
private String getFragmentTag(int tagID){
return "android:switcher:" + R.id.pager + ":" + tagID;
}
}
更新:
我尝试将 FragmentManager 和 ViewPager 引用传递到我的 CustomSimpleCursorAdapter 的构造函数中,但这似乎不起作用。
您可以将用于初始化适配器的上下文转换为 activity(前提是您使用 activity 作为上下文)
public CustomSimpleCursorAdapter(Context context, int layout, Cursor cursor, String[] from, int[] to, int flags) {
super(context, layout, cursor, from, to, flags);
this.context = context;
this.cursor = cursor;
//Where you need to...
((MyActivity)context).mViewPager.setCurrentItem()
}
希望这能让您更好地了解您需要做什么:)
1)创建接口例如:
public interface MyTabChanger{
public void changeTabTo(int nextTabIndex);
}
2) 使用您的片段实现该接口。
3) 在 changeTabTo
中调用您的片段,您可以使用以下代码:
myViewPager.setCurrentItem(nextTabIndex);
4) 更改适配器的构造函数
...
public class CustomSimpleCursorAdapter extends SimpleCursorAdapter {
private Context context;
private Cursor cursor;
private MyTabChanger mCallback;
public CustomSimpleCursorAdapter(MyTabChanger myTabChanger,Context context, int layout, Cursor cursor, String[] from, int[] to, int flags) {
super(context, layout, cursor, from, to, flags);
this.context = context;
this.cursor = cursor;
mCallback = myTabChanger;
}
...
5) 然后在您的适配器中,当您想要更改 viewpager
时只需调用 changeTabTo
。例如:
mCallback.changeTabTo(Constants.TAB_INDEX_STUDENT_INFORMATION);
我认为这是您可以使用的最通用且最干净的解决方案。通过这种方式,您可以将 adapter
与任何 Fragment
和 Activity
一起使用,只要它们实现了 MyTabChanger
。
我的应用程序使用与 ViewPager 关联的 Fragments 来创建选项卡。
在一个选项卡上,我使用 ListView 在 table 中显示我的数据库的内容。我扩展了 SimpleCursorAdapter 以便在我的列表的每一行上执行一些自定义任务(例如,交替行颜色、按钮等)。有一次,我想单击一行中的一个图标并让它切换选项卡,但我在从我的 CustomSimpleCursorAdapter class 中访问 FragmentManager 和 ViewPager 时遇到问题。我可以在片段本身中执行此操作(请参阅注释掉的部分),但是当我切换到使用 CustomSimpleCursorAdapter 时,我失去了这种能力。
那么,如何从我的自定义 class 中访问我的 FragmentManager 和 ViewPager?
注意: 我已经在 CustomSimpleCursorAdapter.java 中标记了我遇到问题的位置
// THIS IS WHERE I AM HAVING ISSUES WITH:
Home.java
package myPackage;
public class Home extends Fragment {
private View rootView;
private CustomSimpleCursorAdapter mySimpleCursorAdapter;
private ViewPager myViewPager;
private SwipeRefreshLayout studentSwipeRefresh;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
rootView = inflater.inflate(R.layout.home, container, false);
myViewPager = (ViewPager) getActivity().findViewById(R.id.pager);
studentSwipeRefresh = (SwipeRefreshLayout) rootView.findViewById(R.id.student_swipe_refresh);
return rootView;
}
@Override
public void onViewCreated(View rootView, Bundle savedInstanceState) {
super.onViewCreated(rootView, savedInstanceState);
drawTheStudentView();
studentSwipeRefresh.setColorSchemeColors(Color.parseColor(Constants.RED), Color.parseColor(Constants.ORANGE), Color.parseColor(Constants.YELLOW), Color.parseColor(Constants.GREEN), Color.parseColor(Constants.BLUE), Color.parseColor(Constants.INDIGO), Color.parseColor(Constants.VIOLET));
studentSwipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
studentSwipeRefresh.setRefreshing(false);
drawTheStudentView();
}
});
}
private void drawTheStudentView(){
DatabaseHelper myDBHelper = new DatabaseHelper(getActivity());
Cursor studentCursor = myDBHelper.getStudentsCursor();
String[] fromColumns = {"_id","studentID","location"};
int[] toViews = {R.id.student_number_textview, R.id.student_id_textview, R.id.student_location.textview};
mySimpleCursorAdapter = new CustomSimpleCursorAdapter(getActivity(), R.layout.student_layout, studentCursor, fromColumns, toViews, 0);
// Replace the _id column with a student count
mySimpleCursorAdapter.setViewBinder(new SimpleCursorAdapter.ViewBinder() {
@Override
public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
String counter = Integer.toString((cursor.getPosition()+1));
TextView modifiedTextView = (TextView) view;
if(columnIndex == 0){
modifiedTextView.setText(counter);
return true;
}
return false;
}
});
ListView myListView = (ListView) rootView.findViewById(R.id.student_row);
// I COMMENTED THIS OUT. THIS WORKS FOR CLICKING THE ENTIRE ROW AND HAVING AN ACTION PERFORMED.
// Listen for somebody clicking on a Student ID, and process
// myListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
// @Override
// public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// Cursor subCursor = (Cursor) mySimpleCursorAdapter.getItem(position);
// String studentIDNumber = subCursor.getString(subCursor.getColumnIndex("studentID"));
//
// StudentInformation studentInformation = (StudentInformation) getFragmentManager().findFragmentByTag(getFragmentTag(Constants.TAB_INDEX_PATIENT_VITALS));
// studentInformation.setStudendIDNumber(studentIDNumber);
//
// myViewPager.setCurrentItem(Constants.TAB_INDEX_STUDENT_LOCATION);
// }
// });
// Draw the list
myListView.setAdapter(mySimpleCursorAdapter);
myDBHelper.close();
}
// Pass me a tab index (see Constants.java) and I'll return a refrence to that tab.
private String getFragmentTag(int tagID){
return "android:switcher:" + R.id.pager + ":" + tagID;
}
}
CustomSimpleCursorAdapter.java
package myPackage;
public class CustomSimpleCursorAdapter extends SimpleCursorAdapter {
private Context context;
private Cursor cursor;
public CustomSimpleCursorAdapter(Context context, int layout, Cursor cursor, String[] from, int[] to, int flags) {
super(context, layout, cursor, from, to, flags);
this.context = context;
this.cursor = cursor;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent){
// Alternate the color of the data rows.
View row = super.getView(position, convertView, parent);
if(position % 2 == 0){
row.setBackgroundColor(Color.parseColor(Constants.WHITE));
} else {
row.setBackgroundColor(Color.parseColor(Constants.LIGHTGREY));
}
// If the "Information" icon/button is clicked, set the information and switch to that tab/fragment.
ImageView statusButton = (ImageView)row.findViewById(R.id.student_status_button);
statusButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View myView) {
cursor.moveToPosition(position);
String studentID = cursor.getString(1);
Toast statusToast = Toast.makeText(context, "Showing information for student " + studentID, Toast.LENGTH_SHORT);
statusToast.show();
// THIS IS WHERE I AM HAVING ISSUES WITH:
// * getFragmentManager()
// * myViewPager.setCurrentItem()
StudentInformation studentInformation = (StudentInformation) getFragmentManager().findFragmentByTag(getFragmentTag(Constants.TAB_INDEX_STUDENT_INFORMATION));
studentInformation.setStudentNumber(studentID);
myViewPager.setCurrentItem(Constants.TAB_INDEX_STUDENT_INFORMATION);
}
});
// If the "Location" button is clicked, then show a Toast with the information.
ImageView locationButton = (ImageView)row.findViewById(R.id.student_location_button);
locationButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View myView) {
cursor.moveToPosition(position);
String studentID = cursor.getString(1);
Toast statusToast = Toast.makeText(context, "Sending location for student " + studentID + " to MESA", Toast.LENGTH_LONG);
statusToast.show();
}
});
return row;
}
// Pass me a tab index (see Constants.java) and I'll return a refrence to that tab.
private String getFragmentTag(int tagID){
return "android:switcher:" + R.id.pager + ":" + tagID;
}
}
更新:
我尝试将 FragmentManager 和 ViewPager 引用传递到我的 CustomSimpleCursorAdapter 的构造函数中,但这似乎不起作用。
您可以将用于初始化适配器的上下文转换为 activity(前提是您使用 activity 作为上下文)
public CustomSimpleCursorAdapter(Context context, int layout, Cursor cursor, String[] from, int[] to, int flags) {
super(context, layout, cursor, from, to, flags);
this.context = context;
this.cursor = cursor;
//Where you need to...
((MyActivity)context).mViewPager.setCurrentItem()
}
希望这能让您更好地了解您需要做什么:)
1)创建接口例如:
public interface MyTabChanger{
public void changeTabTo(int nextTabIndex);
}
2) 使用您的片段实现该接口。
3) 在 changeTabTo
中调用您的片段,您可以使用以下代码:
myViewPager.setCurrentItem(nextTabIndex);
4) 更改适配器的构造函数
...
public class CustomSimpleCursorAdapter extends SimpleCursorAdapter {
private Context context;
private Cursor cursor;
private MyTabChanger mCallback;
public CustomSimpleCursorAdapter(MyTabChanger myTabChanger,Context context, int layout, Cursor cursor, String[] from, int[] to, int flags) {
super(context, layout, cursor, from, to, flags);
this.context = context;
this.cursor = cursor;
mCallback = myTabChanger;
}
...
5) 然后在您的适配器中,当您想要更改 viewpager
时只需调用 changeTabTo
。例如:
mCallback.changeTabTo(Constants.TAB_INDEX_STUDENT_INFORMATION);
我认为这是您可以使用的最通用且最干净的解决方案。通过这种方式,您可以将 adapter
与任何 Fragment
和 Activity
一起使用,只要它们实现了 MyTabChanger
。