如何让自定义列表适配器在片段适配器中工作?

时间:2015-04-27 18:16:43

标签: c# android android-layout android-fragments xamarin

我正在使用自定义适配器来制作包含文本和按钮的自定义列表。 现在我需要在片段中包含该视图,以便我可以在两个不同的视图之间轻松切换。 但我似乎无法弄清楚如何在片段代码中添加活动。是因为我最终在另一个适配器内部安装了适配器吗?

编辑:我的applicantsRequestActivity用于测试自定义列表的功能是否有效我只需要在片段内移动它。

My design

我的主要活动

Activity (Label = "Main")]          
public class Test : FragmentActivity
{


    private ViewPager mViewPager;
    private SlidingTabScrollView mScrollView;


    protected override void OnCreate (Bundle bundle)
    {
        base.OnCreate (bundle);

        // Set our view from the "main" layout resource
        SetContentView (Resource.Layout.FragMain);
        mScrollView = FindViewById<SlidingTabScrollView> (Resource.Id.sliding_tabs);
        mViewPager = FindViewById<ViewPager> (Resource.Id.viewPager);

        // setup mViewPager
        mViewPager.Adapter = new ApplicantsAdapter (SupportFragmentManager);
        mScrollView.ViewPager = mViewPager;


    }


}

我的片段

public class ApplicantsAdapter : FragmentPagerAdapter
{
    private List<Android.Support.V4.App.Fragment> mFragmentHolder;

    public applicantsReqAdapter (Android.Support.V4.App.FragmentManager fragManager) : base (fragManager)
    {
        mFragmentHolder = new List<Android.Support.V4.App.Fragment> ();
        mFragmentHolder.Add (new Applicants ());
        mFragmentHolder.Add (new Acceptes ());
    }

    public override int Count {
        get { return mFragmentHolder.Count; }
    }

    public override Android.Support.V4.App.Fragment GetItem (int position)
    {
        return mFragmentHolder [position];
    }
}

public class Applicants : Android.Support.V4.App.Fragment 
{
    private EditText mTxt;

    public override View OnCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        var view = inflater.Inflate (Resource.Layout.Frag2Layout, container, false);

        mTxt = view.FindViewById<EditText> (Resource.Id.editText1);
        mTxt.Text = "Fragment 1 Class :)";
        return view;
    }

    public override string ToString () //Called on line 156 in SlidingTabScrollView
    {
        return "Fragment 1";
    }
}


public class Acceptes : Android.Support.V4.App.Fragment
{
    private EditText mTxt;

    public override View OnCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        var view = inflater.Inflate (Resource.Layout.Frag2Layout, container, false);

        mTxt = view.FindViewById<EditText> (Resource.Id.editText1);
        mTxt.Text = "Fragment 2 Class :)";
        return view;
    }

    public override string ToString () //Called on line 156 in SlidingTabScrollView
    {
        return "Fragment 2";
    }
}

这是我需要的第一个片段的视图

[Activity (Label = "Applicants")]           
public class applicantsRequestActivity : Activity
{
    DatabaseAccess db = new DatabaseAccess ();
    static ListView applicantsListView;
    static applicantsRequestAdapter listAdapter;
    static List<applicantsRequestList> applicantsList = new List<applicantsRequestList> ();


    //private ViewPager mViewPager;

    protected override void OnCreate (Bundle bundle)
    {
        base.OnCreate (bundle);

        // Set our view from the "main" layout resource


    }


    public void GetApplicants ()
    {
        /*
         get the list from the database

        */


        applicantsList.Add (new PartyRequestList () { applicantsId = 1, Name = "James"});
        applicantsList.Add (new PartyRequestList () { applicantsId = 2, Name = "Thomas"});

    }

    bool isDownloaded = false;

    protected override void OnStart ()
    {
        base.OnStart ();

        applicantsListView = FindViewById<ListView> (Resource.Id.PRR_listView);
        listAdapter = new applicantsRequestAdapter (this, applicantsList);
        applicantsListView.Adapter = listAdapter;

        if (!isDownloaded) {
            ThreadPool.QueueUserWorkItem (o => GetApplicants ());
            isDownloaded = true;
        }
    }           

    public class PartyRequestList
    {
        public int applicantsId { get; set; }

        public string Name { get; set; }

    }
    public class applicantsRequestAdapter : BaseAdapter<PartyRequestList>
    {
        private Button RemoveButton;
        private Button AcceptButton;
        private readonly IList<PartyRequestList> _items;
        private readonly Context _context;

        public applicantsRequestAdapter (Context context, IList<PartyRequestList> items)
        {
            _items = items;
            _context = context;
        }

        public override long GetItemId (int position)
        {
            return position;
        }

        public override int Count {
            get { return _items.Count; }
        }

        public override applicantsRequestList this [int position] {
            get { return _items [position]; }
        }

        public override View GetView (int position, View convertView, ViewGroup parent)
        {
            var item = _items [position];
            var view = convertView;

            if (view == null) {
                var inflater = LayoutInflater.FromContext (_context);
                view = inflater.Inflate (Resource.Layout.applicantsRequestRow, parent, false);

                RemoveButton = view.FindViewById<Button> (Resource.Id.PRR_Remove);
                AcceptButton = view.FindViewById<Button> (Resource.Id.PRR_Accept);
                RemoveButton.Tag = position;
                AcceptButton.Tag = position;
                RemoveButton.Click += RemoveButton_Click;
                AcceptButton.Click += AcceptButton_Click;
            }

            view.FindViewById<TextView> (Resource.Id.PRR_Name).Text = item.Name;                
            return view;
        }

        void RemoveButton_Click (object sender, EventArgs e)
        {
            var pos = (int)((Button)sender).Tag;
            PartyRequestList _aa = applicantsList [pos];
            Toast.MakeText (_context, (String.Format ("Remove: {0} {1}", _aa.Name, pos)), ToastLength.Short).Show ();
            applicantsList.RemoveAt (pos);
            NotifyDataSetChanged ();
        }

        void AcceptButton_Click (object sender, EventArgs e)
        {
            var pos = (int)((Button)sender).Tag;
            PartyRequestList _aa = applicantsList [pos];
            Toast.MakeText (_context, (String.Format ("Accept: {0} {1}", _aa.Name, pos)), ToastLength.Short).Show ();
            NotifyDataSetChanged ();
        }
    }
}

主要文件

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/myDrawer"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#E2E2E2"
    android:id="@+id/sample_main_layout">
    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="@android:color/darker_gray" />
    <SlidingTabLayout.SlidingTabScrollView
        android:id="@+id/sliding_tabs"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <android.support.v4.view.ViewPager
        android:id="@+id/viewPager"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

我用于自定义列表的2 axml

列表axml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ListView
    android:id="@+id/PRR_listView"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" />

行axml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView
    android:id="@+id/PRR_Name"
    android:layout_height="wrap_content"
    android:layout_width="0px"
    android:layout_weight="1"
    android:text="Name" />
<Button
    android:text="Remove"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/PRR_Remove"
    android:tag="Remove" />
<Button
    android:text="Accept"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/PRR_Accept"
    android:tag="Accept" />

1 个答案:

答案 0 :(得分:0)

编辑:我的代码是Java而不是C#。 FYI

您尝试将哪些功能完全保留在片段中? 不幸的是,我认为您无法在片段中获得活动的全部功能,但您可以使用getActivity访问它,例如:

getActivity().getSupportActionBar().setText("Title Bar Text here"); 

或直接喜欢:

MainActivity.staticMethod()

这是myListFragment类

public class MyListFragment extends Fragment {

private final String LOG_TAG = MainActivity.class.getSimpleName();
private customList = new ListAdapater<RowItem>;
private static ListView projectListView;


public MyListFragment() {
}

public void add(View view)
{
    Intent newIntent = new Intent(getActivity(), NewActivity.class);
    startActivity(newIntent);
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // Add this line in order for this fragment to handle menu events.
    setHasOptionsMenu(true);
        }

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();
    return super.onOptionsItemSelected(item);
}



@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    // The ArrayAdapter will take data from a source (DB/JSON Object) and
    // use it to populate the ListView it's attached to.
    // Get current list adapter from main and set it here to the rootview for this
    // list fragment
    //userDataAdapter = MainActivity.getListAdapter();
    View rootView = inflater.inflate(R.layout.fragment_listview, container, false);
    projectListView = (ListView) rootView.findViewById(R.id.listview);

    //Fill in list data
    if (mySnapshot != null) {
        for (DataSnapshot project : mySnapshot.getChildren() ) {
            if (project.child("Name").getValue() != null) {

                //Get Project Details from Firebase JSON
                String pName = project.child("Name").getValue().toString();
                String pDesc = project.child("Description").getValue().toString();
                int statusImageId = Utility.getStatusImage(Integer.parseInt(project.child("Status").getValue().toString()));

                //Create RowItem for ArrayList
                RowItem proj = new RowItem(statusImageId, pName, pDesc);

                //Add RowItem to the adapter arraylist
                customList.add(proj);
            }

        }
    }

    //set custom list
    projectListView.setAdapter(customList);

    //Set list click listener, if an item is clicked(selected) then we will change view
    //to the nexst list
    projectListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
            //Handle list item clicks here.
        }
    });      
    return rootView;
}

}

这是我的自定义适配器的样子:

public class ListAdapter extends ArrayAdapter<RowItem> {
//Context for the current view
Context context;


public ListAdapter(Context context, ArrayList<RowItem> items) {
    super(context, R.layout.list_item_layout, items);
    this.context = context;
}

/**
 * getView method returns the individual row views inflated so they can be displayed in the list
 * @param position position of the RowItem being requested in the ArrayList
 * @param convertView view to hold the entire row view before it is passed back to the ListView
 * @param parent reference to the ListView where the row will be shown.
 * @return view is given back to the listView so only displayed items + 1 on each side will stay
 *          android in memory
 */
public View getView(int position, View convertView, ViewGroup parent) {
    View view = convertView;
    if(view == null)
    {
        LayoutInflater mInflater = (LayoutInflater) context
                .getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
        view = mInflater.inflate(R.layout.list_item_layout, parent, false);
    }

    TextView txtDesc = (TextView) view.findViewById(R.id.description);
    TextView txtTitle = (TextView) view.findViewById(R.id.title);
    ImageView imageView = (ImageView) view.findViewById(R.id.icon);

    txtDesc.setText(getItem(position).getDesc());
    txtTitle.setText(getItem(position).getTitle());
    imageView.setImageResource(getItem(position).getImageId());
    return view;
}

}

我的RowItem类只有两个用于title / desc的字符串和一个用于保存image_id引用的字符串。

应该注意的是,片段是在我的MainActivity中使用以下内容启动的:     if(savedInstanceState == null){             getSupportFragmentManager()。的BeginTransaction()                     .add(R.id.container,new MyListFragment())                     。承诺();         }

其他档案:

main.xml中

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
tools:ignore="MergeRootFrame"
/>

listview.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<ListView
android:id="@+id/listview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight = "1"
/>
<!-- Add Button -->
<Button android:id="@+id/btnAdd"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="10dip"
    android:onClick="add"
    android:text="Add New"/>
</LinearLayout>

编辑:添加了代码 - 希望我没有错过任何内容。

编辑:这是github https://github.com/thurst0n/Archie上这个项目的链接。这可能更有意义,但请忽略我的错误编码实践,其中大部分是为了学校而被抛在一起。我记得特别有问题,最初让listview工作在一个片段而不仅仅是一个简单的活动。另请注意,我只是为每个级别换出列表适配器而不是创建列表片段的另一个实例,这是一个设计选择,使其他功能更容易实现,但可能不是很好的设计实践。我认为正确的方法是让fragmentmanager处理后台堆栈。

//Use this for something?
public void setContent(Fragment fragment)
{
    getSupportFragmentManager().beginTransaction()
            .replace(R.id.container, new MyListFragment())
            .commit();
}