Как я могу подключить свой класс ListAdapter для работы во фрагменте с настроенным классом «Модель» для строк?

1

Я пытаюсь создать персонализированный 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
    }
}

Мой фрагмент_хом .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>

Предполагается, что я должен иметь возможность запускать свой настраиваемый ListView из моего HomeFragment и оттуда иметь возможность щелкнуть по элементу в списке и показать Toast (в конце концов, другой фрагмент, но обо всем по порядку), На данный момент у меня есть настроенные строки и ListView готов, но я не могу установить соединение от MyListAdapter к HomeFragment.

Теги:
kotlin

2 ответа

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

Пойдет:

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

Контекст (this.context, где это ваш HomeFragment, а контекст взят из getContext()) будет использоваться в вашем адаптере для заполнения строки списка (resource = R.layout.row)

В случае, если вам нужна ваша активность в качестве контекста, вы можете создать экземпляр адаптера списка следующим образом:

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

где активность от getActivity()

В любом случае вы получите доступ к ресурсам вашего приложения, чтобы получить Model.img.

  • 0
    Спасибо @alexscmar, но я не могу заставить контекст работать. Поскольку MyListAdapter расширяет ArrayAdapter , я не могу заставить его работать, принимая фрагмент как параметр вместо контекста . Возможно, вы знаете альтернативу Context и Activity, которую я могу передать в качестве параметра и все равно буду работать с ArrayAdapter ?
  • 0
    Может быть, вы можете использовать BaseAdapter вместо ArrayAdapter ... Позвольте мне лучше проверить ваш код.
Показать ещё 2 комментария
0

MyListAdapter должен иметь возможность взять ссылку на фрагмент вместо Context (Activity), если вы измените тип параметра и локальную переменную в MyListAdapter, тогда вам просто нужно передать "this" и синтаксис такой же, как у Деятельность. Если это не сработает, то вам может понадобиться получить Fragment Context (Activity) onCreate() и сохранить его для использования при создании MyListAdapter. Мне придется взглянуть на мои примеры кода завтра для примера...

Хорошо, вот как я это делаю:

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;
                }

            }
  • 0
    Спасибо @MichaelDougan, теперь я изменил это в HomeFragment, но он не примет этот @ HomeFragment в качестве параметра ... val list = mutableListOf<Model>() listView.adapter = MyListAdapter(this@HomeFragment, R.layout.row, list) и я как-то понимаю почему, так как я изменил параметры MyListAdapter, чтобы взять действие вместо контекста, но я не знаю, что заменить его class MyListAdapter (var mCtx: Activity, var resource: Int, var items: List<Model>) :ArrayAdapter<Model>(mCtx, resource, items){

Ещё вопросы

Сообщество Overcoder
Наверх
Меню