نوشتن رویداد onClick برای سوئیچ کردن بین اکتویتی
سلام دوستان. من میخوام با کلیک روی یکی از دکمه های آیتم RecyclerView، به اکتیویتی دیگه منتقل بشم و همراهش یه مقداری رو putExtra کنم. الان هر کاری میکنم، خطای nullPointerException میده. اینم کد:
public class AdapterRecyclerView extends RecyclerView.Adapter<AdapterRecyclerView.viewHolder>{ private LayoutInflater inflater; List<Information> data = Collections.emptyList(); public AdapterRecyclerView(Context context, List<Information> data){ inflater=LayoutInflater.from(context); this.data=data; } @Override public viewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = inflater.inflate(R.layout.adapter_recycler, parent, false); viewHolder holder = new viewHolder(view); return holder; } @Override public void onBindViewHolder(viewHolder holder, final int position) { Information current = data.get(position); holder.title.setText(current.p_uname); holder.desc.setText(current.p_desc); holder.btnProfile.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intentRegister = new Intent(G.currentActivity, ActivityShopProfile.class); intentRegister.putExtra("POSITION", position); G.currentActivity.startActivity(intentRegister); } }); } @Override public int getItemCount() { return data.size(); } class viewHolder extends RecyclerView.ViewHolder{ TextView title; TextView desc; FrameLayout btnProfile; public viewHolder(View itemView) { super(itemView); title = (TextView) itemView.findViewById(R.id.txtTitle); desc = (TextView) itemView.findViewById(R.id.txtDesc); btnProfile = (FrameLayout) itemView.findViewById(R.id.btnProfile); } } }
من رویداد کلیک رو داخل onBind نوشتم. نمیدونم چرا از همون خط اول اینتنت خطا میگیره
وقتی که برنامتون خطا میده، متن خطا رو درج کنید. من توی کدتون خطایی نمیبینم، ولی 3 مسئاله هست:
1: باید تیک clicable رو برای btnProfile در adapter_recycler تیک بزنید.
2: نباید اسم گذاریتون به طوری باشه که از FrameLayout استفاده کنید و اسم ویوتون رو btn... بذارید.
3: زمانی که میخواید روی کل یک آیتم کلیک ست کنید نباید در adapter کلیک رو بنویسید، باید در اکتیویتی از متد:
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { } });
استفاده کنید.(متد بالا در لیست ویو و RecyclerView کاملا مشابه نوشته میشه)
خطایی که درج کردید 2 دلیل میتونه داشته باشه:
1: کلاس G رو در منیفست تعریف نکردید، یا در اکتیویتی تون به currentActivity مقدار ندادید.
2: کلاس ActivityShopProfile رو در منیفست تعریف نکردید،
که به احتمال 99% مورد اول رعایت نشده.
ببینید شما وقتی میخواید از G.currentActivity استفاده کنید، باید به هر اکتیویتی که میرید بگید
G.currentActivity = this;
این currentActivity که در کلاس G تعریف کردید یک متغیر استاتیک هست، و خودش خود به خود نمیتونه تشخیص بده که شما توی کدوم اکتیویتی هستی، پس باید مقدار دهی بشه.
میتونید در onCreate هر اکتیویتی کد بالا رو درج کنید، ولی اگر بازگشت به اکتیویتی هم دارید میتونید در متد onResume کد بالا رو بنویسید.
اومدم با position دریافتی، ID مورد نظرم رو گرفتم از توی آرایه
توی یه ترد نوشتم که ID رو پست کن به سرور و پاسخ سرور رو که یک کد جیسون هست رو بگیر و ذخیره کن توی یه آرایه و توی TextView ها نشونشون بده:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_shop_profile); G.currentActivity = this; //Get Extra Bundle extras = getIntent().getExtras(); int position = 0; if (extras != null){ position = extras.getInt("POSITION"); Log.e("LOG", "POSITION: " +position); } final Information shopId = G.ilamList.get(position); //Error final int id = shopId.p_uid; final String finalId = Integer.toString(id); //end //Post kardane id Thread postThread = new Thread(new Runnable() { @Override public void run() { try { ArrayList<NameValuePair> params = new ArrayList<NameValuePair>(); params.add(new BasicNameValuePair("Userid", finalId)); Log.i("LOG", "PHONE_NUMBER: " + params); String responseText = PostClass.readUrl(url, params); JSONArray jsonCategory = new JSONArray(responseText); for (int i = 0; i < jsonCategory.length(); i++) { JSONObject object = jsonCategory.getJSONObject(i); Information categoty = new Information(); categoty.p_uname = object.getString("p_uname"); categoty.rp_title = object.getString("p_title"); categoty.p_desc = object.getString("p_desc"); categoty.p_gpaddress = object.getString("p_gpaddress"); categoty.p_address = object.getString("p_address"); categoty.ygps = object.getString("ygps"); categoty.xgps = object.getString("xgps"); categoty.p_mobile = object.getString("p_mobile"); categoty.p_tell = object.getString("p_tell"); categoty.p_payment = object.getString("p_payment"); G.ilamList.add(categoty); } } catch (Exception e) { e.printStackTrace(); } } }); postThread.start(); //tarife kontrolha //ImageView imgProfile = (ImageView) findViewById(R.id.imgProfile); TextView txtName = (TextView) findViewById(R.id.txtName); TextView txtDesc = (TextView) findViewById(R.id.txtDesc); TextView txtAddress = (TextView) findViewById(R.id.txtAddress); TextView txtPhone = (TextView) findViewById(R.id.txtPhone); //end txtName.setText(shopId.p_uname); txtDesc.setText(shopId.p_desc); txtAddress.setText(shopId.p_address); txtPhone.setText(shopId.p_tell);
اینم خطای لوگ کت:
برای تایید پاسخ و همچنین تشکر به پاسخ امتیاز بدید(لایک کنید) و من هیچ وقت از پاسخ به سوالات شما دوستان عزیز اذیت نمیشم، من از همینجا برنامه نویسی اندروید رو شروع کردم و الان با پاسخ دادن به شما وظیفه ام رو انجام میدم.
شما position رو درست میگیرید، ولی وقتی به وب سرویس ارسال میکنید هیچ چیزی برنمیگردونه، مشکل میتونه حالت های مختلف داشته باشه.
1: توی دیتابیستون چک کنید که همین position که مقدار 0 داره وجود داشته باشه. اگر دارید id رو select میکنید، شاید در دیتابیس از 1 شروع کردید و position از 0 شروع میشه.
2: شاید وب سرویستون مشکل داره و ArrayList رو به درستی برنمیگردونه.
3: باید زمانی از ArrayList استفاده کنید که دیتا رو از وب سرویس دریافت کرده باشید. در حالت بالا شما میگید دیتا رو از وب سرویس بگیر و زمان نمیدید که دیتا گرفته بشه و بعد دیتا رو ست کنید. خوب مسلما دیتا خالیه.
4: باید برای وب سرویستون یک interface تعریف کنید که زمانی که دیتا رو گرفت، اگر دیتا خالی نبود یک متد که در اون عملیات ست کردن دیتا وجود داره رو اجرا کنه.
مشکلی نیست الان در دریافت ID و درست دریافت و پستش میکنم. اطلاعات هم درست از سرور دریافت میکنم و همینطور، درست توی آرایه ذخیرش میکنم. فقط مشکل اینجاس که اون اطلاعات رو نمیتونم توی TextView ها نشون بدم. وارد این صفحه میشم، صفحه خالیه. باید چیکار کنم که وقتی اطلاعات رو دریافت و ذخیره میکنم توی آرایه، اونا رو توی TextView ها نشون بده؟
اینم کد:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_shop_profile); G.currentActivity = this; //Get Extra Bundle extras = getIntent().getExtras(); int position = 0; if (extras != null){ position = extras.getInt("POSITION"); Log.e("LOG", "POSITION: " +position); } Information shopId = G.ilamList2.get(position); finalId = Integer.toString(shopId.p_uid); Log.e("LOG", "SHOPID: " + finalId); //end //Post kardane id Thread postThread = new Thread(new Runnable() { @Override public void run() { try { G.ilamList2.clear(); ArrayList<NameValuePair> params = new ArrayList<NameValuePair>(); params.add(new BasicNameValuePair("Userid", finalId)); Log.i("LOG", "PHONE_NUMBER: " + params); String responseText = PostClass.readUrl(url, params); JSONObject json = new JSONObject(responseText); Information categoty = new Information(); //categoty.p_uname = object.getString("p_uname"); categoty.s_title = json.getString("p_title"); categoty.s_desc = json.getString("p_desc"); categoty.p_gpaddress = json.getString("p_gpaddress"); categoty.p_address = json.getString("p_address"); categoty.ygps = json.getString("ygps"); categoty.xgps = json.getString("xgps"); categoty.p_mobile = json.getString("p_mobile"); categoty.p_tell = json.getString("p_tell"); categoty.p_payment = json.getString("p_payment"); categoty.p_group = json.getString("p_group"); categoty.p_state = json.getString("p_state"); Log.i("LOG", "PHONE_NUMBER: " + categoty.s_title); G.ilamList2.add(categoty); } catch (Exception e) { e.printStackTrace(); } } }); postThread.start(); //tarife kontrolha //ImageView imgProfile = (ImageView) findViewById(R.id.imgProfile); TextView txtName = (TextView) findViewById(R.id.txtName); TextView txtDesc = (TextView) findViewById(R.id.txtDesc); TextView txtAddress = (TextView) findViewById(R.id.txtAddress); TextView txtPhone = (TextView) findViewById(R.id.txtPhone); //end txtName.setText(shopId.s_title); txtDesc.setText(shopId.s_desc); txtAddress.setText(shopId.p_address); txtPhone.setText(shopId.p_tell);
}
اروری هم نمایش نمیده
ببین احسان جان، من هنوزم نمیدونم چرا کدت درست کار میکنه و اررور نمیده. در کد بالا شما اول shopId رو مقدار میدی، بعد میای میگی از وب سرویس اطلاعات رو بگیر و اطلاعات جدید رو که گرفتی در G.ilamList2.add(categoty); قرار بده. خوب این کار از نظر اصولی اشتباهه. شما نباید متغیر استاتیک استفاده کنی(در اینجا). باید زمانی که وب سرویس آرایه رو برمیگردونه توی یک ArrayList یا یک متغیر از نوع Information که خودتم همین کار رو کردی، درست کنی و اطلاعات رو بگیری. پس کاری که باید بکنی اینه که position رو برای وب سرویس بفرستی و یک ArrayList بگیری ازش، بعد یک متغیر Information درست میکنی و آیتم مورد نظرت رو توی position میریزی و در آخر همینجوری که تکست ویو هارو setText کردی پرشون میکنی.
کد زیر نحوه ریختن دیتا از ArrayList به یک متغیر، و در نهایت ست کردن برای تکست ویو هست:
ArrayList<Information> arrayList = new ArrayList<Information>; arrayList = data; // data = لیستی که از وب سرویس میگیرید Information info = (Information) arrayList.get(position); txtName.setText(info.s_title);
شما هم همین کار ها رو کردید. ولی زمانی که دارید مقادیر رو از وب سرویس میگیرید، در آرایه ای در کلاس G مقادیر رو پر میکنید ولی زمانی که دارید توی تکست ویو مقادیر رو setText میکنید از یک متغیر دیگه که اطلاعات رو من نمیدونم از کجا بهش دادید ست میکنید.
الان اگر شما کد زیر رو بنویسید باید درست بشه، ولی به نظرم روشتون یکم اشتباهه.
Information info = (Information) G.ilamList2.get(position); txtName.setText(info.s_title); txtDesc.setText(info.s_desc); txtAddress.setText(info.p_address); txtPhone.setText(info.p_tell);
پاسخگویی و مشاهده پاسخ های این سوال تنها برای اعضای ویژه سایت امکان پذیر است .
چنانچه تمایل دارید به همه بخش ها دسترسی داشته باشید میتوانید از این بخش لایسنس این آموزش را خریداری نمایید .