如何连接我的ListAdapter类以在具有针对行的自定义“模型”类的片段中工作?

时间:2019-04-23 23:20:54

标签: android kotlin

我正在尝试按照教程制作的应用程序中创建自定义ListView。如果您想从活动中启动ListView,则本教程效果很好,但是我试图使它在片段内部工作,而且似乎无法弄清楚如何将适配器连接到片段。 有谁知道我该怎么解决?在这一点上,Kotlin对我来说还很陌生,因此可能有一个明显的解决方案,我只是还没有找到它。

我确实可以通过将代码附加到活动上来工作,但是在我的项目中,我试图将其附加到导航栏中的片段上,但是该片段将无法处理活动中使用的代码。

这是将onCreate方法中的代码附加到活动后的样子:

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        //listview
        var listView = findViewById<ListView>(R.id.listView)

        var list = mutableListOf<Model>()

        //adding items to the listview
        list.add(Model("title one", "description one....", R.drawable.imgone))
        list.add(Model("title two", "description two....", R.drawable.imgtwo))
.....

        //adapter
        listView.adapter = MyListAdapter(this, R.layout.row, list)

        //ListView item clicks
        listView.setOnItemClickListener { parent, view, position, id ->
            if (position == 0){
                Toast.makeText(this@MainActivity, "Item One clicked", Toast.LENGTH_LONG).show()
            }
            if (position == 1){
                Toast.makeText(this@MainActivity, "Item Two clicked", Toast.LENGTH_LONG).show()
            }
.....
        }

    }

这是这段代码在片段中的样子

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        val view = inflater.inflate(R.layout.fragment_home, container, false)

        val listView: ListView = view.findViewById(R.id.homeListView)

        val adapter: MyListAdapter
        //Not sure how to instantiate MyListAdapter

        return view
    }

Model类如下

class Model(val title: String, val desc: String, val img: Int)

MyListAdapter看起来像这样

class MyListAdapter (var mCtx: Context, var resource: Int, var items: List<Model>)
    :ArrayAdapter<Model>(mCtx, resource, items){


    override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {

        val layoutInflater: LayoutInflater = LayoutInflater.from(mCtx)

        val view: View = layoutInflater.inflate(resource, null)
        val imageView: ImageView = view.findViewById(R.id.list_view_image)
        val titleView: TextView = view.findViewById(R.id.list_view_title_txt)
        val descTView: TextView = view.findViewById(R.id.list_view_desc_txt)

        var mItems: Model = items[position]

        imageView.setImageDrawable(mCtx.resources.getDrawable(mItems.img))
        titleView.text = mItems.title
        descTView.text = mItems.desc


        return view
    }
}

我的fragment_home.xml使用一个非常简单的ListView:

<ListView
            android:id="@+id/homeListView"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

    </ListView>

虽然row.xml可以自定义列表中项目的外观

<LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:padding="10dp">

    <ImageView
            android:id="@+id/list_view_image"
            android:layout_width="80dp"
            android:layout_height="80dp"
            android:contentDescription="@string/list_view_img_content_desc"/>

    <LinearLayout
            android:layout_margin="5dp"
            android:layout_gravity="center"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

        <TextView
                android:id="@+id/list_view_title_txt"
                android:text="@string/list_view_title"
                android:textSize="15sp"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"/>
        <TextView
                android:id="@+id/list_view_desc_txt"
                android:text="@string/list_view_desc"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"/>

    </LinearLayout>

</LinearLayout>

应该做的是,我应该能够从HomeFragment中启动自定义的ListView,然后从中单击列表中的项目并显示Toast(最终会出现另一个Toast,但首先首先。 目前,我已经准备好自定义的行和ListView,但是似乎无法建立从MyListAdapter到HomeFragment的连接。

2 个答案:

答案 0 :(得分:0)

只要您更改MyListAdapter中的参数类型和局部变量,MyListAdapter应该能够引用片段而不是上下文(活动),然后,您只需传递“ this”并且语法与活动的内容。如果这不起作用,那么您可能需要获取Fragment的Context(活动)onCreate()并将其保存以用于创建MyListAdapter。我明天要看我的代码示例作为示例...

好的,这就是我的做法(很抱歉,它不在Kotlin中):

FavoritesFragment.java

            package org.mycompany.myapp;

            import java.util.ArrayList;
            import java.util.HashMap;
            import java.util.Map;

            import org.json.JSONArray;
            import org.json.JSONException;
            import org.json.JSONObject;
            import org.mycompany.TEST.adapter.FavoriteListAdapter;
            import org.mycompany.TEST.model.FavoriteItem;

            import android.app.Fragment;
            import android.app.ProgressDialog;
            import android.content.Context;
            import android.content.Intent;
            import android.view.LayoutInflater;
            import android.view.View;
            import android.view.ViewGroup;
            import android.widget.AdapterView;
            import android.widget.ListView;

            public class FavoritesFragment extends Fragment {

                Context thisContext;
                private MainActivity myActivity;

                private ViewGroup container;
                private View rootView;

                private ListView mFavoriteList;                 
                private ArrayList<FavoriteItem> favoriteItems;
                private FavoriteListAdapter adapter;
                private FavoritesFragment thisFragment;

                public FavoritesFragment(){}

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

                    rootView = inflater.inflate(R.layout.fragment_favorites, container, false);
                    this.container = container;

                    //Get a reference to the fragments activity 
                    myActivity = (MainActivity)getActivity();   

                    RestoreAllItems();

                    //Declare the favorite array
                    favoriteItems = new ArrayList<FavoriteItem>();

                    //Load the favorite array
                    callGetFavorites();

                    return rootView;

                }

                private void RestoreAllItems()
                {

                    //Get a reference to the fragments Context
                    thisContext = container.getContext();

                    //Get a reference to the Fragment
                    thisFragment = this;

                    mFavoriteList = (ListView) rootView.findViewById(R.id.list_browse);

                    mFavoriteList.setOnItemClickListener(new FavoriteClickListener());


                }

                /**
                 * Item click listener
                 * */
                private class FavoriteClickListener implements ListView.OnItemClickListener {
                    @Override
                    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

                        FavoriteItem item = favoriteItems.get(position);

                            Intent iIntent = new Intent(thisContext, DetailActivity.class);

                            iIntent.putExtra("animal_id", item.getAnimalID());

                            startActivityForResult(iIntent, ACTIVITY_PET_DETAIL);

                    }
                }  

                //Method called from the ListAdapter when an items checkbox changes
                public void checkChanged(int position, boolean isChecked) {

                    if (position < favoriteItems.size()) {      
                        FavoriteItem item = favoriteItems.get(position);
                        item.setSelected(isChecked);

                        favoriteItems.set(position, item);
                    }


                }

                //Load the favoriteItems array
                private void getFavorites(String url) {
                    final ProgressDialog dialog;    

                    dialog = new ProgressDialog(thisContext);         
                    dialog.setMessage("Loading, please wait...");         
                    dialog.setIndeterminate(true);         
                    dialog.setCancelable(false);         
                    dialog.show();     

                    favoriteItems = new ArrayList<FavoriteItem>();

                    JsonArrayRequest req = new JsonArrayRequest(url, new Response.Listener<JSONArray> () {  

                        @Override
                        public void onResponse(JSONArray response) {
                            try {
                                ....

                                for (int i = 0; i < response.length(); i++) {

                                ....

                                    // Load the favoriteItems array
                                    favoriteItems.add(new FavoriteItem(name, breed, sex, age_long, animal_id));

                                }

                                try {

                                    //When the array is fully loaded set the ListAdapter
                                    adapter = new FavoriteListAdapter(thisContext, favoriteItems, thisFragment);
                                    mFavoriteList.setAdapter(adapter);

                                } catch (Exception e) {
                                   e.printStackTrace();
                                } 

                            } catch (JSONException e) {
                                e.printStackTrace();
                            }

                            dialog.dismiss();
                        }


                    }, new Response.ErrorListener() {
                        @Override
                        public void onErrorResponse(VolleyError error) {
                            VolleyLog.e("Error: ", error.getMessage());
                            Log.e("Error: ", error.getMessage());
                            dialog.dismiss();
                        }
                    }) {

                       @Override
                       public Map<String, String> getHeaders() throws AuthFailureError {
                           HashMap<String, String> headers = new HashMap<String, String>();
                                String authValue = "Bearer " + apiToken;
                                headers.put("Authorization", authValue);
                                headers.put("Accept", "application/json; charset=UTF-8");
                                headers.put("Content-Type", "application/json; charset=UTF-8");
                           return headers;
                       };
                    };

                    // add the request object to the queue to be executed
                    MyApplication.getInstance().addToRequestQueue(req);
                }   
            }

然后,ListAdapter: FavoriteListAdapter.java

            package org.mycompany.TEST.adapter;

            import java.util.ArrayList;

            import org.mycompany.TEST.FavoritesFragment;
            import org.mycompany.TEST.R;
            import org.mycompany.TEST.model.FavoriteItem;

            import android.app.Activity;
            import android.content.Context;
            import android.view.LayoutInflater;
            import android.view.View;
            import android.view.ViewGroup;
            import android.widget.BaseAdapter;
            import android.widget.CheckBox;
            import android.widget.CompoundButton;
            import android.widget.CompoundButton.OnCheckedChangeListener;
            import android.widget.ImageView;
            import android.widget.TextView;


            public class FavoriteListAdapter extends BaseAdapter {

                private Context context;
                private FavoritesFragment thisFragment;
                private ArrayList<FavoriteItem> favoriteItems;
                private boolean isEditing = false;


                public FavoriteListAdapter(Context context, ArrayList<FavoriteItem> favoriteItems, FavoritesFragment thisFragment){
                    //Reference to the Context
                    this.context = context;
                    //Reference to the ArrayList
                    this.favoriteItems = favoriteItems;
                    //Reference to the Fragment that created the ListAdapter
                    this.thisFragment = thisFragment;
                }

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

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

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

                @Override
                public View getView(int position, View convertView, ViewGroup parent) {

                    if (convertView == null) {
                        //Context allows you to get the LayoutInflater
                        LayoutInflater mInflater = (LayoutInflater)context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
                        convertView = mInflater.inflate(R.layout.favorite_list_item, null);
                    }

                     TextView txtName = (TextView) convertView.findViewById(R.id.name);
                    CheckBox chkSelected = (CheckBox) convertView.findViewById(R.id.isSelected);

                    txtName.setText(favoriteItems.get(position).getName());
                    chkSelected.setChecked(favoriteItems.get(position).isSelected());
                    //Store the position in the list of this list item
                    chkSelected.setTag("" + position);
                    chkSelected.setOnCheckedChangeListener(new OnCheckedChangeListener() 
                    {

                        public void onCheckedChanged(CompoundButton chkBox, boolean isChecked) 
                        {
                            //Get the position out of the tag when the checkbox changes
                            String sPos = (String) chkBox.getTag();
                            int position = Integer.parseInt(sPos);

                            //Call the checkChanged method in the Fragment
                            thisFragment.checkChanged(position, isChecked);
                        }
                    });

                    return convertView;
                }

            }

答案 1 :(得分:0)

 val adapter: MyListAdapter
    //Not sure how to instantiate MyListAdapter

会去:

listView.adapter = MyListAdapter(context, R.layout.row, list)

上下文 this.context ,其中 this 是您的HomeFragment,上下文来自getContext() )会在您的适配器中用于向您添加列表行(resource = R.layout.row)

在需要将活动作为上下文的情况下,可以实例化列表适配器,如下所示:

listView.adapter = MyListAdapter(activity, R.layout.row, list)

活动来自 getActivity()

无论哪种情况,您都可以访问应用程序的资源以获取Model.img。