我正在尝试按照教程制作的应用程序中创建自定义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的连接。
答案 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。