如何从Android中的活动访问自定义适配器内部片段的UI元素

时间:2015-02-11 23:12:10

标签: android listview android-fragments view interface

美好的一天,我正在开发一个应用程序,我有多个活动(活动A,B,B),这个活动会膨胀这个片段(TheListFragment)。

这是它的外观的直观表示: ListView picture

目前,我可以从Fragment本身更改描述,图像等,但这不是我想要做的。我的目标是让各自的活动都能够更改片段并将片段用作可重复使用的列表视图。以下是我的一些代码:

public class TheListFragment extends Fragment {

    CustomAdapter.Holder holder;

    //The listview
    ListView listView;

    //When the view is created
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        //Inflate the add new game layout view
        View view = inflater.inflate(R.layout.list_view_holder, container, false);

        //Setup the listview and reference it to the listview id
        listView = (ListView) view.findViewById(R.id.data_list_view);

        //Set the custom adapter to the listview
        listView.setAdapter(new CustomAdapter(context);

        return view;
    }

    //This custom adapter is used to fill the respective data into the listview
    class CustomAdapter extends BaseAdapter {
        Context context;

        public CustomAdapter(Context context)) {
            this.context = context;
            inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        }

        @Override
        public int getCount() {
            return all_passed_data.size();
            //List of data. removed it for space purposes
        }

        @Override
        public Object getItem(int position) {
            return position;
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        //Holds the respective fields
        public class Holder {
            //UI Components
            TextView textview;
            ImageView imageView;

            LinearLayout linearLayout;
        }

        //Custom view
        public View getView(final int position, View convertView, ViewGroup parent) {

            //A holder object to reference the textviews and imageviews
            holder = new Holder();
            View rowView;
            rowView = inflater.inflate(R.layout.custom_list_view, null);

            holder.imageView = (ImageView) rowView.findViewById(R.id.custom_list_view_image);

            holder.textview = (TextView) rowView.findViewById(R.id.custom_list_view_game_name);

            holder.linearLayout = (LinearLayout) rowView.findViewById(R.id.left_layout);

            return rowView;
        }
    }
}

我正在尝试从膨胀片段本身的活动中设置/更改listView内容(持有者类项)。 IE,有点像这样:

public class ActivityA extends Activity{

    FragmentManager manager;
    ListFragment fragment;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.list_fragment_holder);

        manager = getFragmentManager();

        ListFragment fragment = (ListFragment) manager.findFragmentById(R.id.the_list_fragment);

        //These will not work at the moment, they read as null pointers
        //This will be changed dynamically depending on the activity. Could be checkbox, imageview, etc.
        fragment.holder.linearLayout.addView(holder.checkBox); 

        fragment.holder.textview.setText("I Want to set the text here");    

        //Make it do something when clicked 
        fragment.holder.textview.setOnClickListener(this); 

        //Use third party library picasso to set the image
        fragment.Picasso.with(context).load("http://www.google.com/somepicture").into(holder.imageview); 

    }
}

但我没有运气弄清楚如何实现这一目标。我已阅读以下链接:Call fragment events from activityAndroid: Reusing same View object in different Activities (the case is about ad banners)How to access UI elements created by a List Adapter from an Activity?。我是否需要实现以某种方式访问​​数据的接口?如果是这样,怎么样?或者其他一些我失踪的方法?

1 个答案:

答案 0 :(得分:2)

所以这是我认为的完整答案。

首先让每个班级做好自己的工作。所以Activity有Fragments和Fragments有适配器和适配器有Holders。

使用您需要的方法创建一个abatract Fragment,然后通过使它们扩展为抽象的片段来创建该片段的具体版本。

抽象片段中的一个方法应该是public void doSomething();。

在你的片段的具体版本(A B o C)中,实现了你在doSomething()方法上做实际“某事”的方法。在这些framgents使用某种收集来保存所需的信息(我使用arraylist)。这是列表中的实际数据,持有者将根据需要进行瞳孔显示在屏幕上。在你的情况下,以免假设将文本放在屏幕上的元素。这实际上应该是一个代表屏幕上elemtens的类,即具有所有需要显示的elemtns的类GameItem,甚至是复选框状态。代表游戏。

然后在您的适配器(自定义适配器)中,您必须从保持活动接收两个参数上下文和arraylist(包含文本数组或100%正确应该接收游戏数组)。同样在这个适配器中创建一个名为public void changeGameInfo()的公共方法;在方法中,您可以更改所接收数组的内容。当您填充列表并获取适当的值以显示在屏幕上时,持有者将加入该元素。

在您的班级中,您可以创建片段的实例。在正确的时间调用您在片段中创建的方法,ieregreg.doSomething();在doSomething中你调用adapter.changeGameInfo();因为是包含适配器实例的片段。并且由于适配器具有您作为参数传递的游戏的arraylist的参考,我将知道需要显示的elemetn,就是这样,

所以作为简历 XXXX类调用fragment.doSomething()。 在fragment.doSoemthing中,你调用adapter.changeGameInfo() 在适配器中,您可以改变作为参数的arraylist所需的游戏表示。 viewholder只显示元素,更改数组列表上的elemnts之后记得调用notifyDataSetChanged();在adpter中,屏幕上的实际值会自动更新

查看viewholder patter的示例

public class InteractiveArrayAdapter extends ArrayAdapter<Model> {

private final List<Model> list;
private final Activity context;

public InteractiveArrayAdapter(Activity context, List<Model> list) {
  super(context, R.layout.rowbuttonlayout, list);
  this.context = context;
  this.list = list;
}

static class ViewHolder {
  protected TextView text;
  protected CheckBox checkbox;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
  View view = null;
  if (convertView == null) {
    LayoutInflater inflator = context.getLayoutInflater();
    view = inflator.inflate(R.layout.rowbuttonlayout, null);
    final ViewHolder viewHolder = new ViewHolder();
    viewHolder.text = (TextView) view.findViewById(R.id.label);
    viewHolder.checkbox = (CheckBox) view.findViewById(R.id.check);
    viewHolder.checkbox
      .setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

        @Override
        public void onCheckedChanged(CompoundButton buttonView,
            boolean isChecked) {
          Model element = (Model) viewHolder.checkbox
              .getTag();
          element.setSelected(buttonView.isChecked());

        }
      });
  view.setTag(viewHolder);
  viewHolder.checkbox.setTag(list.get(position));
} else {
  view = convertView;
  ((ViewHolder) view.getTag()).checkbox.setTag(list.get(position));
}
ViewHolder holder = (ViewHolder) view.getTag();
holder.text.setText(list.get(position).getName());
holder.checkbox.setChecked(list.get(position).isSelected());
return view;
}
}