繁体   English   中英

Android如何从ListView元素打开片段

[英]Android how to open fragment from listview element

MainActivity是FrameLayout MainContainer 我在其中加载片段TrainerMyGroups ,在Listview中,我使用TrainerGroupsAdapter添加了一些元素(每个元素都有一些字符串)。 其实我想替换片段TrainerMyGroups另一个(例如TrainersInfo通过点击列表中的元素)。

我的TrainerGroupsAdapter是:

public class TrainerGroupsAdapter extends ArrayAdapter {

    List list = new ArrayList();

    public TrainerGroupsAdapter(Context context, int resource) {
        super(context, resource);
    }

    static class Datahandler{
        TextView name;
        TextView when;
        TextView where;
        LinearLayout ll;
    }

    @Override
    public void add(Object object) {
        super.add(object);
        list.add(object);
    }

    @Override
    public int getCount() {
        return this.list.size();
    }

    @Override
    public Object getItem(int position) {
        return this.list.get(position);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View row;
        row=convertView;
        Datahandler handler;
        SharedPreferences pref = getContext().getSharedPreferences("pref", Context.MODE_PRIVATE);

        if(convertView==null){
            LayoutInflater inflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            row= inflater.inflate(R.layout.list_mygroups,parent,false);
            handler = new Datahandler();
            handler.name =  (TextView) row.findViewById(R.id.trainermygroupslistname);
            handler.where =  (TextView) row.findViewById(R.id.trainermygroupslistwhere);
            handler.when =  (TextView) row.findViewById(R.id.trainermygroupslistwhen);
            handler.ll=(LinearLayout) row.findViewById(R.id.trainermygroupslistlayout);
            row.setTag(handler);
        }
        else {
            handler = (Datahandler)row.getTag();
        }

        TrainerGroupsDataProvider dataProvider;
        dataProvider = (TrainerGroupsDataProvider)this.getItem(position);
        handler.name.setText(dataProvider.getName());
        handler.when.setText(dataProvider.getWhen());
        handler.where.setText(dataProvider.getWhere());
        handler.ll.setBackgroundColor(Color.parseColor(pref.getString(TRANSP_KEY, "#CC") + dataProvider.getColor()));


        handler.ll.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                getFragmentManager().beginTransaction().replace(R.id.MainContainer, new TrainerInfo()).addToBackStack(null).commit();
            }
        });


        return row;
    }

}

它不起作用,但是OnClick方法可能很好,因为如果我替换getFragmentManager().beginTransaction().replace(R.id.MainContainer, new TrainerInfo()).addToBackStack(null).commit(); 编写代码来更改某些字符串(名称,在tc时)有效。 问题出在getFragmentMenager() ,Android Studio显示消息我必须创建Getter,AS的建议是在OnClick方法中生成:

private FragmentManager fragmentManager;
public FragmentManager getFragmentManager() {
      return fragmentManager;
}

然后问题出在replace中的第二个参数中,我有一个错误,那就是它必须是Fragment(我肯定TrainersInfo()是fragment,因为我在其他地方使用了它并且可以工作)。 如何解决此问题,或者单击另一个片段中的lise元素,打开片段的最佳方法是什么?

#UPDATE2

最好然后在适配器内替换Fragment,这是说您的活动是应该替换该片段。 这可以通过您在Activity中实现的接口来完成:

public class TrainerGroupsAdapter extends ArrayAdapter {
    // The interface which you have to implement in your activity
    public interface OnChangeFragmentListener {
        void changeFragment();
    }

    List list = new ArrayList();
    private OnChangeFragmentListener m_onChangeFragmentListener;

    public TrainerGroupsAdapter(Context context, int resource) {
        super(context, resource);
        m_onChangeFragmentListener = (OnChangeFragmentListener) context;
    }

    // Your other code

}

您的getView方法中的OnClickListener:

handler.ll.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        // Call the method which change the fragment
        m_onChangeFragmentListener.changeFragment();
    }
});

活动:

public class MainActivity extends AppCompatActivity implements TrainerGroupsAdapter.OnChangeFragmentListener {

    //...
    //  Your Other code

    // Implement the method which is called in the adapter and replace the fragment here
    @Override
    public void changeFragment() {
        getFragmentManager().beginTransaction().replace(R.id.MainContainer, new TrainerInfo()).addToBackStack(null).commit();
    }
}

#UPDATE1

您需要getSupportFragmentManager()和getFragmentManager()的活动上下文。 您可以将构造函数的Context参数更改为Activity,并在类中为该活动创建一个成员变量,以便以后使用:

public class TrainerGroupsAdapter extends ArrayAdapter {

    List list = new ArrayList();
    private Activity m_activity;

    public TrainerGroupsAdapter(Activity context, int resource) {
        super(context, resource);
        m_activity = context;
    }
    // Your other code
}

您的getView方法中的OnClickListener:

   handler.ll.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            m_activity.getFragmentManager().beginTransaction().replace(R.id.MainContainer, new TrainerInfo()).addToBackStack(null).commit();
        }
   });

正在寻找类似的答案,并从一个好朋友和Android开发者那里得到了一个答案。 我认为这是最容易理解和实施的工具。 因此,我通常会创建一个帮助器类,在其中放置两个静态函数以打开片段(作为替换或对话框):

例如替换一个:

public static void openFragmentReplace(Activity activity, int idOfPlacement, Fragment fragment) 
    final FragmentManager fm = ((FragmentActivity)activity).getSupportFragmentManager();
    final FragmentTransaction fragmentTransaction = fm.beginTransaction();
    fragmentTransaction.replace(idOfPlacement, fragment);
    fragmentTransaction.commit();
}

和对话框之一:

public static void openFragmentAsDialog(Activity activity, DialogFragment fragment) {
    final FragmentManager fm = ((FragmentActivity)activity).getSupportFragmentManager();
    fragment.show(fm, "tag");
}

然后我从我想要的地方这样调用它:

Helper.openFragmentReplace(getActivity(),R.id.PlaceForFragment,FragmentClass newFrag);

这似乎是最好,最简单的方法!

希望能帮助到你。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM