ClassCastException error when using setOnScrollListener - java

Below is a code where data will come at scrolling time but there is an error i.e
ClassCastException. Please help me to solve this error. Now I have added my whole fragment class Similar_Matchs_Tab where we fetching the from server.
java.lang.ClassCastException: com.devbhoomimedia.maangal.ProfilesActivity cannot be cast to android.widget.AbsListView$OnScrollListener
public class Similar_Matchs_Tab extends Fragment {
private ListView listView;
public Similar_Matchs_Tab() {}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
JSON_URL = "https://www.maangal.com/maangal_mobile/similar_matches.php?matri_id="+email;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Inflate the layout for this fragment
View view= inflater.inflate(R.layout.matches_tab, container, false);
listView = (ListView) view.findViewById(R.id.listView);
listView.setOnScrollListener((AbsListView.OnScrollListener) getActivity());
sendRequest();
listView.setOnScrollListener(new AbsListView.OnScrollListener() {
#Override
public void onScrollStateChanged(AbsListView absListView, int i) {
}
#Override
public void onScroll(AbsListView absListView, int i, int i1, int i2) {
}
});
return view;
}
sendRequest function to fetch the data
private void sendRequest(){
final ProgressDialog loading = ProgressDialog.show(getActivity(),"Loading Data", "Please wait...",false,false);
StringRequest stringRequest = new StringRequest(Request.Method.POST,JSON_URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
loading.dismiss();
showJSON(response);
Log.e("Similar MAtches******",response);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getContext(),error.getMessage(), Toast.LENGTH_LONG).show();
}
});
int MY_SOCKET_TIMEOUT_MS = 30000;
stringRequest.setRetryPolicy(new DefaultRetryPolicy(
MY_SOCKET_TIMEOUT_MS, DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
RequestQueue requestQueue = Volley.newRequestQueue(getContext());
requestQueue.add(stringRequest);
}
protected void showJSON(String json){
ParseJSON pj = new ParseJSON(json);
pj.parseJSON();
Profile_Match_custom_List cl = new Profile_Match_custom_List(getActivity(), ParseJSON.ids,ParseJSON.ages, ParseJSON.heights, ParseJSON.communities,ParseJSON.castes,ParseJSON.educations,ParseJSON.occupations,ParseJSON.incomes,ParseJSON.pics,ParseJSON.locations,ParseJSON.shortlist,ParseJSON.expressinterest);
listView.setAdapter(cl);
}
}

B'coz you're casting Activity into AbsListView.OnScrollListener interface that's why you're getting classCastException.
just remove listView.setOnScrollListener((AbsListView.OnScrollListener) getActivity());
and replace
listView.setOnScrollListener((ProfileActivity) getActivity());

The reason why you're getting this error is because you're trying to cast activity to a scroll listener which is not possible. So to fix the problem just set the appropriate interface and it should work. Replace listView.setOnScrollListener((AbsListView.OnScrollListener) getActivity()); with this:
lv.setOnScrollListener(new AbsListView.OnScrollListener() {
#Override
public void onScrollStateChanged(AbsListView absListView, int i) {
}
#Override
public void onScroll(AbsListView absListView, int i, int i1, int i2) {
}
});

change it
listView.setOnScrollListener((AbsListView.OnScrollListener) getActivity());
to
listView.setOnScrollListener((ProfileActivity)getActivity());
and ProfileActivity must implements AbsListView.OnScrollListener.

Your activity does not implement AbsListView.OnScrollListener interface.

Related

Swipe to refresh data using SwipeRefreshLayout in fragment?

I want my layout to be refreshed when the app starts and the data should show in and when the user swipes the data should be updated and show new data if new data is available on the server.
The actual problem is that the data is not loading when the app is started. Rather it is happening only on swiping. How can I achieve that on opening the app the data is loaded first and then the data is updated on swiping?
public class FirstFragment extends Fragment {
FragmentFirstBinding binding;
APIInterfaces interfaces;
ArrayList<VideoModels> list = new ArrayList<>();
#Override
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
binding = FragmentFirstBinding.inflate(inflater, container, false);
MyAdapter adapter = new MyAdapter(list,getContext());
binding.myRecyclerView.setAdapter(adapter);
GridLayoutManager gridLayoutManager = new GridLayoutManager(getContext(),2);
binding.myRecyclerView.setLayoutManager(gridLayoutManager);
interfaces = RetrofitInstance.getRetrofit().create(APIInterfaces.class);
binding.swipeToRefresh.setRefreshing(true);
binding.swipeToRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
interfaces.getPosts().enqueue(new Callback<List<VideoModels>>() {
#SuppressLint("NotifyDataSetChanged")
#Override
public void onResponse(#NonNull Call<List<VideoModels>> call, #NonNull Response<List<VideoModels>> response) {
list.clear();
if (response.isSuccessful()) {
assert response.body() != null;
list.addAll(response.body());
adapter.notifyDataSetChanged();
binding.swipeToRefresh.setRefreshing(false);
}
}
#Override
public void onFailure(#NonNull Call<List<VideoModels>> call, #NonNull Throwable t) {
Toast.makeText(getContext(), "Check you Internet", Toast.LENGTH_SHORT).show();
binding.swipeToRefresh.setRefreshing(false);
}
});
}
});
binding.swipeToRefresh.setRefreshing(false);
return binding.getRoot();
}
}
EDIT-1: Added complete code.
Your answer will helpful for me.
You need to call this method in onResume() state
public void getData() {
interfaces.getPosts().enqueue(new Callback<List<VideoModels>>() {
#SuppressLint("NotifyDataSetChanged")
#Override
public void onResponse(#NonNull Call<List<VideoModels>> call, #NonNull Response<List<VideoModels>> response) {
list.clear();
if (response.isSuccessful()) {
assert response.body() != null;
list.addAll(response.body());
adapter.notifyDataSetChanged();
binding.swipeToRefresh.setRefreshing(false);
}
}
#Override
public void onFailure(#NonNull Call<List<VideoModels>> call, #NonNull Throwable t) {
Toast.makeText(getContext(), "Check you Internet", Toast.LENGTH_SHORT).show();
binding.swipeToRefresh.setRefreshing(false);
}
});
}
if you call binding.swipeLayout.isRefreshing = true
in SwipeRefreshLayout source code, mNotify boolean value is false
so cannot do anything in setOnRefreshListener
public void onAnimationEnd(Animation animation) {
if (mRefreshing) {
// Make sure the progress view is fully visible
mProgress.setAlpha(MAX_ALPHA);
mProgress.start();
if (mNotify) {
if (mListener != null) {
mListener.onRefresh();
}
}
mCurrentTargetOffsetTop = mCircleView.getTop();
} else {
reset();
}
}
this is why setOnRefreshListener not invoke
if you want manual invoke it do like this by reflect set mNotify boolean value is true
val swipeClass = SwipeRefreshLayout::class.java
val method = swipeClass.getDeclaredMethod("setRefreshing", Boolean::class.java, Boolean::class.java)
method.isAccessible = true
method.invoke(binding.swipeLayout, true, true)
After finding the solution for 1 day. Finally, I found my solution.
To use SwipeRefreshLayout work in Fragment and want to refresh your data Onswipe. use the below code and modify it as your requirement.
This is a fragment.
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
binding = FragmentFirstBinding.inflate(inflater, container, false);
// swiping on starting of an app.
binding.swipeToRefresh.setRefreshing(true);
getData();
binding.swipeToRefresh.setRefreshing(false);
// when user swipe
binding.swipeToRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#SuppressLint("NotifyDataSetChanged")
#Override
public void onRefresh() {
getData();
}
});
return binding.getRoot();
}
public void getData(){
// you have to put all of your onCreate code here to work properly. most of time it throws an error. So, make sure you added code properly.
ArrayList<VideoModels> list = new ArrayList<>();
MyAdapter adapter = new MyAdapter(list,getContext());
GridLayoutManager gridLayoutManager = new GridLayoutManager(getContext(),2);
binding.myRecyclerView.setAdapter(adapter);
binding.myRecyclerView.setLayoutManager(gridLayoutManager);
binding.swipeToRefresh.setRefreshing(true);
interfaces = RetrofitInstance.getRetrofit().create(APIInterfaces.class);
interfaces.getPosts().enqueue(new Callback<List<VideoModels>>() {
#SuppressLint("NotifyDataSetChanged")
#Override
public void onResponse(#NonNull Call<List<VideoModels>> call, #NonNull Response<List<VideoModels>> response) {
list.clear();
if (response.isSuccessful()) {
assert response.body() != null;
list.addAll(response.body());
adapter.notifyDataSetChanged();
binding.swipeToRefresh.setRefreshing(false);
}
}
#Override
public void onFailure(#NonNull Call<List<VideoModels>> call, #NonNull Throwable t) {
Toast.makeText(getContext(), "Check you Internet", Toast.LENGTH_SHORT).show();
binding.swipeToRefresh.setRefreshing(false);
}
});
}

Trying to insert to database with methods from MainActivity from Fragment

im newbie with fragment, and i want to insert some data into database from Fragment with methods from MainActivity
here is my code
LaporanFragment
public class LaporanFragment extends Fragment{
EditText judulL, isiL;
TextView nomor_ktp, ambilNama;
ImageView fotoL;
Button kirim;
private ProgressDialog progressDialog;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_laporan, container, false);
judulL = (EditText) v.findViewById(R.id.judulLaporan);
isiL = (EditText) v.findViewById(R.id.isiLaporan);
nomor_ktp = (TextView) getActivity().findViewById(R.id.nomor_ktp);
final String noktp = nomor_ktp.getText().toString();
//fotoL = (ImageView) v.findViewById(R.id.foto_laporan);
final String jdlLaporan = judulL.getText().toString();
final String isiLaporan = isiL.getText().toString();
kirim = (Button) v.findViewById(R.id.kirim_laporan);
kirim.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
((MainActivity)getActivity()).kirim_lapor(jdlLaporan, isiLaporan, noktp);
}
});
return v;
}
and MainActivity with kirim_lapor method
public void kirim_lapor(final String judul, final String isi, final String username){
StringRequest stringRequest = new StringRequest(Request.Method.POST,
Constants.URL_LAPOR,
new Response.Listener<String>(){
#Override
public void onResponse(String response){
//progressDialog.dismiss();
try{
JSONObject jsonObject = new JSONObject(response);
//Toast.makeText(LaporanFragment.this, jsonObject.getString("message"), Toast.LENGTH_LONG).show();
}catch(JSONException e){
e.printStackTrace();
}
}
},
new Response.ErrorListener(){
#Override
public void onErrorResponse(VolleyError error){
//progressDialog.hide();
//Toast.makeText(getApplicationContext(), error.getMessage(), Toast.LENGTH_LONG).show();
}
}){
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
params.put("judul_laporan", judul);
params.put("isi_laporan", isi);
params.put("no_ktp", username);
return params;
}
};
RequestHandler.getInstance(this).addToRequestQueue(stringRequest);
}
the problem is when i press button kirim in fragment, the app will crash
please help me guys, sorry for my bad english.
To localize and hinder further error, instead of calling the MainActivity method via casting the getActivity(), you should make a Listener for telling the Activity about the data.
Create the interface for Listener in Fragment:
public class LaporanFragment extends Fragment {
private LaporanListener mListener;
// Define a Listener to 'speak up' to the main activity
public interface LaporanListener {
public void onSendReportClicked(String title, String content, String idNumber);
}
...
}
When clicking the button sendReport, use the listener:
public class LaporanFragment extends Fragment {
...
...
kirim.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
mListener.onSendReportClicked(jdlLaporan, isiLaporan, noktp);
}
});
...
...
}
Then you need to implement the interface Listener to the MainActivity:
public class MainActivity extends Activity implements LaporanFragment.LaporanListener {
...
#Override
public void onSendReportClicked(String title, String content, String idNumber) {
// MainActivity will receive the data here.
// You need to process here.
}
...
}
For further reading, read Creating Custom Listeners.

How can I send data from PageAdapter to an activity that extends Activity class

I have a problem in my android app. In my app after click on btn_back_story01, I need to send a boolean variable (that called newPermit) from a PageViewer (that called customeSwipeAdapter) to an activity that extends Activity class. The pageViewer is:
public class CustomSwipeAdapter01 extends PagerAdapter {
private int[] image_Resources = {R.drawable.sample_01, R.drawable.sample_02, R.drawable.sample_03, R.drawable.sample_04, R.drawable.sample_05, R.drawable.sample_06, R.drawable.sample_07};
private Context ctx;
private LayoutInflater layoutInflater;
boolean newPermit;
public CustomSwipeAdapter01(Context ctx) {
this.ctx = ctx;
}
#Override
public int getCount() {
return image_Resources.length;
}
#Override
public boolean isViewFromObject(View view, Object o) {
return (view == (RelativeLayout) o);
}
#Override
public Object instantiateItem(final ViewGroup container, final int position) {
layoutInflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final View item_view = layoutInflater.inflate(R.layout.activity_story01, container, false);
ImageView imageView = (ImageView) item_view.findViewById(R.id.image_view);
TextView textView = (TextView) item_view.findViewById(R.id.image_count);
Button btn_back_story01 = (Button) item_view.findViewById(R.id.btn_back_story01);
imageView.setImageResource(image_Resources[position]);
int itemNo = position + 1;
textView.setText(itemNo + "/" + getCount());
container.addView(item_view);
newPermit=false;
btn_back_story01.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
newPermit = true;
((Activity) ctx).finish();
ctx.startActivity(intent);
boolean over=false;
}
});
return item_view;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((RelativeLayout) object);
}}
and the activity is:
public class Story01 extends Activity {
ViewPager viewPager;
CustomSwipeAdapter01 adapter;
Button btn_back_story01;
boolean permit, oldPermit;
protected TestClass app;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_viewer);
app = (TestClass) getApplication();
viewPager = (ViewPager) findViewById(R.id.view_pager);
btn_back_story01 = (Button) findViewById(R.id.btn_back_story01);
adapter = new CustomSwipeAdapter01(this);
viewPager.setAdapter(adapter);
}
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
}
}
#Override
protected void onStart() {
permit = false;
super.onStart();
}
#Override
protected void onStop() {
if (permit == false) {
app.musicStop();
}
Intent intent = new Intent(getApplicationContext(), MainStory01.class);
startActivity(intent);
finish();
super.onStop();
}}
I know it is simple but when you don't know a simple thing it will be difficault.
You can use a listener. You create an interface which you can make callbacks with. Then you make you activity implement this and make sure its passed to your adapter to use.
CustomSwipeAdapter01
public class CustomSwipeAdapter01 extends PagerAdapter {
public interface NewPermitListener {
void onPermitClicked(boolean over);
}
private NewPermitListener mListener;
...
public CustomSwipeAdapter01(Context ctx, NewPermitListener listener) {
this.ctx = ctx;
// pass the listener in the constructor
mListener = listener;
}
...
#Override
public Object instantiateItem(final ViewGroup container, final int position) {
...
btn_back_story01.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
...
// call the method
mListener.onPermitClicked(false);
}
});
return item_view;
}
}
Story01
public class Story01 extends Activity implements CustomSwipeAdapter01.NewPermitListener{
...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_viewer);
...
// pass the listener in here
adapter = new CustomSwipeAdapter01(this, this);
viewPager.setAdapter(adapter);
}
#Override
public void onPermitClicked(boolean over) {
// do something with boolean
}
...
}

java.lang.IllegalStateException: Activity has been destroyed when using datetime picker library

I am new to Android development.
I want to create a customized date and time picker in my Application.
I downloaded this library from github to achieve this.
When I try to use it in my application, it crashes and I got the following error:
java.lang.IllegalStateException: Activity has been destroyed
Can anybody look at my code to see what I am missing?
import jp.seesaa.android.datetimepicker.date.DatePickerDialog;
import jp.seesaa.android.datetimepicker.time.RadialPickerLayout;
import jp.seesaa.android.datetimepicker.time.TimePickerDialog;
/**
* Created by MAC12 on 20-Apr-15.
*/
public class HomeFragment extends Fragment implements DatePickerDialog.OnDateSetListener, TimePickerDialog.OnTimeSetListener {
public HomeFragment(){
}
String tg="HomeFragment ";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_home, container, false);
// cls.findViewById(R.layout.fragment_home).setOnClickListener();
return rootView;
}
#Override
public void onViewCreated(View view,Bundle savedInstanceState)
{
super.onViewCreated(view, savedInstanceState);
Button button = (Button) view.findViewById(R.id.date_picker_day);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ActivityCls cls=new ActivityCls();
cls.Start();
}
});
}
#Override
public void onDetach() {
super.onDetach();
try {
Field childFragmentManager = Fragment.class.getDeclaredField("fragment_home");
childFragmentManager.setAccessible(true);
childFragmentManager.set(this, null);
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
public class ActivityCls extends FragmentActivity
{
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// findViewById(R.layout.date_picker_day).setOnClickListener();
DatePickerDialog.newInstance(HomeFragment.this, 2006, 1, 2)
.show(getSupportFragmentManager(), "datepicker");
}
public void Start()
{
DatePickerDialog.newInstance(HomeFragment.this, 2006, 1, 2)
.show(getSupportFragmentManager(), "datepicker");
}
}
#Override
public void onStart() {
super.onStart();
}
#Override
public void onStop() {
// Log.w(TAG, "App stopped");
super.onStop();
}
#Override
public void onDestroy() {
// Log.w(TAG, "App destoryed");
super.onDestroy();
}
#Override
public void onDateSet(DatePickerDialog dialog, int year, int monthOfYear, int dayOfMonth) {
}
#Override
public void onTimeSet(RadialPickerLayout view, int hourOfDay, int minute) {
}
}
http://developer.android.com/guide/topics/ui/controls/pickers.html here you can see the format of the date is moth day and year, you are pasing year before then you have that exception.

OnItemClickListener is not being called

I have an ItemClickListener in a gridview. But my itemclicklistener is not being called. There is no activity on item click of the gridview
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
vi = inflater.inflate(R.layout.home, container, false);
Button startdialog = (Button) vi.findViewById(R.id.btnCreateDialog);
startdialog.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent startdialog = new Intent(getActivity(),
start_dialog.class);
startActivity(startdialog);
}
});
Button iv = (Button) vi.findViewById(R.id.btnMoreDialog);
iv.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
PopupMenu homepopup = new PopupMenu(getActivity(), v);
MenuInflater inflater = homepopup.getMenuInflater();
inflater.inflate(R.menu.moredialog, homepopup.getMenu());
homepopup.show();
}
});
PremiumgridView = (StaggeredGridView) vi
.findViewById(R.id.premiumstaggeredGridView);
new Dialogs().execute(urls);
return vi;
}
private class Dialogs extends AsyncTask<String[], Void, String[]> {
#Override
protected String[] doInBackground(String[]... params) {
return params[0];
}
protected void onPostExecute(String[] result) {
int premiummargin = getResources().getDimensionPixelSize(
R.dimen.margin);
PremiumgridView.setItemMargin(premiummargin);
PremiumgridView.setPadding(premiummargin, 0, premiummargin, 0);
final StaggeredAdapter premiumadapter = new StaggeredAdapter(
vi.getContext(), R.id.photoimageview, result,
R.layout.row_staggered_demo);
PremiumgridView.setAdapter(premiumadapter);
premiumadapter.notifyDataSetChanged();
premiumadapter.onClick(vi);
PremiumgridView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(StaggeredGridView parent, View view,
int position, long id) {
String item = premiumadapter.getItem(position).toString();
Toast.makeText(getActivity(), premiumadapter.getItem(position), Toast.LENGTH_SHORT).show();
// Toast.makeText(getActivity(), "You have chose: "+ item, Toast.LENGTH_LONG).show();
}});
}
#Override
protected void onPreExecute() {
}
}
Anyone please?
Thanks,
Solved the problem by removing the button from the xml. Clickable item cannot have another clickable item inside it. Reference OnItemClickListener Not Triggered on Android GridView
Does it crash? If yes, always provide us with the Stacktrace/Logcat.
As far as I know, it´s impossible to directly change the interface from within any Thread other than the UI-Thread - you could either try Handler or use this.
EDIT: OnPostExecute is actually called on the UI-Thread, so this is not a solution for this problem. (see here)

Categories