我正在使用Json为应用程序获取数据和图像。这些图像显示在RecolyerView中,该View位于连接到MainActivity的片段(Tab1.java)的内部。我想以这样的方式设置它,这样当用户单击RecyclerView中的一个图像时,就启动了一个新的活动(viewImage.java),图像就显示在那里。
到目前为止,我已经能够获取Json数据并将其显示在一个回收器视图中。图像显示得很好,但当我尝试设置“SetItemonClickListener”时,应用程序开始崩溃(我在Tab1.java中用注释标记了这一行)。
表1.Java
/*
* A simple {@link Fragment} subclass.
* Activities that contain this fragment must implement the
* {@link Tab1.OnFragmentInteractionListener} interface
* to handle interaction events.
* Use the {@link Tab1#newInstance} factory method to
* create an instance of this fragment.
*/
public class Tab1 extends Fragment implements CardAdapter.OnItemClickListener{
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
public static final String EXTRA_URL = "imageUrl";
private RecyclerView mRecyclerView;
private CardAdapter mCardAdapter;
private ArrayList<Card> mCardList;
TextView textView;
private OnFragmentInteractionListener mListener;
public Tab1() {
// Required empty public constructor
}
/*
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* @param param1 Parameter 1.
* @param param2 Parameter 2.
* @return A new instance of fragment Tab1.
*/
// TODO: Rename and change types and number of parameters
public static Tab1 newInstance(String param1, String param2) {
Tab1 fragment = new Tab1();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
// @Override
public void onCreate(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_tab1, container, false);
mRecyclerView = v.findViewById(R.id.recycler_view);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
mCardList = new ArrayList<>();
/*
* Retrofit code to fetch the Json data
*/
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(ApiService.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
ApiService service = retrofit.create(ApiService.class);
Call<JsonResponse> call = service.getPopulationData();
final StringBuffer flagData = new StringBuffer();
call.enqueue(new Callback<JsonResponse>(){
@Override
public void onResponse(Call<JsonResponse> call, Response<JsonResponse> response) {
ArrayList<Worldpopulation> population=new ArrayList(response.body()
.getWorldpopulation());
for (Worldpopulation j : population) {
String countryName = j.getCountry();
String imageUrl = j.getFlag();
int rank = j.getRank();
mCardList.add(new Card(imageUrl, countryName, rank));
}
mCardAdapter = new CardAdapter(getActivity(), mCardList);
mRecyclerView.setAdapter(mCardAdapter);
// This particular line of code is causing the application to crash.
// And I cannot figure out how this is supposed to be implemented.
mCardAdapter.setItemOnClickListener((CardAdapter.OnItemClickListener) getContext());
}
@Override
public void onFailure(Call<JsonResponse> call, Throwable t) {
Log.d("JSONError", t.getMessage());
}
});
// Inflate the layout for this fragment
return v;
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
@Override
public void onItemClick(int position) {
Intent imagePreview = new Intent(getActivity(), ViewImage.class);
Card clickedItem = mCardList.get(position);
imagePreview.putExtra(EXTRA_URL, clickedItem.getImageUrl());
startActivity(imagePreview);
}
/*
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
}
CardAdapter.java
public class CardAdapter extends RecyclerView.Adapter<CardAdapter.CardViewHolder> {
private Context mContext;
private ArrayList<Card> mCardList;
private OnItemClickListener mListener;
public interface OnItemClickListener {
void onItemClick(int position);
}
public void setItemOnClickListener(OnItemClickListener listener) {
mListener = listener;
}
public CardAdapter(Context context, ArrayList<Card> cardList) {
mContext = context;
mCardList = cardList;
}
@Override
public CardViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(mContext).inflate(R.layout.card, parent, false);
return new CardViewHolder(v);
}
@Override
public void onBindViewHolder(CardViewHolder holder, int position) {
Card currentItem = mCardList.get(position);
String imageUrl = currentItem.getImageUrl();
String countryName = currentItem.getCountryName();
int rank = currentItem.getRank();
holder.mTextViewCountry.setText(countryName);
holder.mTextViewRank.setText("Rank: " + rank);
Picasso.get().load(imageUrl).fit().centerInside().into(holder.mImageView);
}
@Override
public int getItemCount() {
return mCardList.size();
}
public class CardViewHolder extends RecyclerView.ViewHolder {
public ImageView mImageView;
public TextView mTextViewCountry;
public TextView mTextViewRank;
public CardViewHolder(View itemView) {
super(itemView);
mImageView = itemView.findViewById(R.id.image_view);
mTextViewCountry = itemView.findViewById(R.id.text_view_country_name);
mTextViewRank = itemView.findViewById(R.id.text_view_rank);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mListener != null) {
int position = getAdapterPosition();
if (position != RecyclerView.NO_POSITION) {
mListener.onItemClick(position);
}
}
}
});
}
}
}
ViewImage.java
public class viewimage extends appcompatactivity {
@override
protected void oncreate(bundle savedinstancestate) {
super.oncreate(savedinstancestate);
setcontentview(r.layout.activity_view_image);
// imageview where the image is to be displayed in this activity
imageview imageview = findviewbyid(r.id.fullscreenimage);
bundle bundle = getintent().getextras();
if (bundle != null) {
string imageurl = bundle.getstring("extra_url");
if (imageurl != null) {
picasso.get().load(imageurl).fit().centerinside().into(imageview);
}
}
}
}
正如您已经知道的,此方法在RecyclerView
类中不再可用。
我在RecyclerView
中实现OnClick
事件的方法如下所示:
class MyAdapter extends RecyclerView.Adapter<MyViewHolder> {
interface OnClickListener {
void onClick(Item item);
}
private final List<Item> dataset;
private final OnClickListener l;
public MyAdapter(List<Item> data, OnClickListener listener) {
this.dataset = data;
this.l = listener;
}
@Override MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = //inflate layout
MyClick click = new MyClick() {
onClick(int position) {
if (l != null) {
l.onClick(dataset.get(position));
}
}
};
return new MyViewHolder(click, v);
}
static class MyViewHolder {
final MyClick l;
public MyViewHolder(MyClick listener, View view) {
super(view);
l = listener;
// inflate views
view.setOnClickListener(new OnClickListener() {
if (l != null) {
l.onClick(getAdapterPosition());
}
});
}
interface MyClick {
void onClick(int position);
}
}
}
class MyActivity extends AppCompatActivity {
@Override void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// set layout
MyAdapter adapter = new MyAdapter(getData(), new OnClickListener() {
@Override onClick(Item item) {
// do stuff with item
}
});
}
}
问题内容: 我阅读了很多有关片段的文章,但是我仍然对如何做感到困惑。 我有一个MainActivity,它并排显示两个片段。在一个片段中,我有一个按钮,并在该片段的片段布局XML中定义 现在我要实现该方法 我以为必须在FragmentA.java中实现,而不是在MainActivity.java中实现。但是,只有在MainActivity.java中实现了该方法后,该方法才有效。这是为什么?对我而
我在一个xml布局文件中声明了许多按钮,并将此布局用于一个片段。 令人失望的是,“onclickbutton”事件被捕捉在主机activity,而不是在我的片段。当然,在我的片段中,我可以手动解决这个问题,如下所示: 有没有显式的方法来处理片段中的onClickbutton事件?
我得到了这个错误,但我不知道是什么原因导致的...也许是因为它是在一个片段中初始化的,而不是在activity本身。编辑:包含的StatsAdapter代码
我想在收到一些HTTP请求的响应后,更新几个<code>片段 。-- 活动 适配器 碎片样本 日志显示位置0,1处的片段的<code>updateData</code>工作良好。但是对于位置2处的片段,它会导致错误。 我发现的区别是适配器没有为位置2调用,这意味着没有调用的。因此不存在。 我的直觉告诉我,问题一定来自适配器的工作流或fragmentManager事务。但是作为一个Android初学
我有一个包含大量成员的类,我想检查每个成员是否为null。我不想手动添加它,只要运行一个for循环(或类似的东西),每次添加一个字段时,它将遍历所有字段,而不需要“人工”添加。 到目前为止,我可以查看字段,并收到字段的名称(这是我所需要的)。然而,字段上并没有检查其值是否为null的内容。 以下是我目前掌握的情况: - 在此示例中,打印将为: 缺少名称1 缺少名称3
我使用的是onSavedInstanceState()方法,这样在旋转设备后,我的textview就不会丢失它的值,但我会遇到我在活动中提到的崩溃。 以下是我的活动