I use this code to update the listview of my project but i get duplicates by using the listview.invalidateViews(); method. Also i tried the notifyDataSetChanged method by calling it from the customadapter of mine that extends baseadapter but it does not seem to work properly. I need to update using the postexecute method after downloading the data from online source. Please check below my code.
The HomeFragment
public class HomeFragment extends Fragment {
private HomeViewModel homeViewModel;
Bitmap mIcon12;
private ProgressDialog pDialog;
private ArrayList< String> arrayList;
ArrayList<HashMap<String,String>> aList;
private int scrollState;
private int offset = 0;
private Button btnLoadMore;
private boolean flag = false;
private boolean loadingMore = false;
TextView textinput2;
ImageView lv1;
View root;
View root1;
ProgressBar pb;
private int scrollpos;
private ListView lv;
public ArrayList<SubjectData> arrayList1;
CustomAdapter adapter1;
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container,Bundle savedInstanceState) {
homeViewModel =
new ViewModelProvider(this).get(HomeViewModel.class);
root = inflater.inflate(R.layout.fragment_home, container, false);
root1 = inflater.inflate(R.layout.listitem, container, false);
final TextView textView = root.findViewById(R.id.text_home);
lv = root.findViewById(R.id.homelistview);
lv1=root1.findViewById(R.id.flagimageview);
arrayList1 = new ArrayList<SubjectData>();
lv.setClickable(true);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Object o = lv.getItemAtPosition(position);
Toast.makeText(getContext(), "myPosss "+position, Toast.LENGTH_LONG).show();
}
});
MainActivity main1 = (MainActivity)getActivity();
if (savedInstanceState == null) {
adapter1 = new CustomAdapter(getContext(), arrayList1);
System.out.println("to lv den ine null edopoooooooooooo");
} else {
}
pb = new ProgressBar(getContext());
lv.addFooterView(pb);
lv.setAdapter(adapter1);
if (!flag) {
new loadMoreListView().execute();
flag = true;
System.out.println("to flag1 ine: "+ flag);
}
lv.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
int totalItemCount) {
scrollpos = totalItemCount;
int lastPos = firstVisibleItem + visibleItemCount;
if ((lastPos == totalItemCount) && (!loadingMore)) {
if (totalItemCount < 250) {
System.out.println("to flag4 ine " + flag);
new loadMoreListView().execute();
} else {
lv.removeFooterView(pb);
}
}
}
});
homeViewModel.getText().observe(getViewLifecycleOwner(), new Observer<String>() {
@Override
public void onChanged(@Nullable String s) {
textView.setText(s);
}
});
return root;
}
private class loadMoreListView extends AsyncTask< Void, Void, String> {
protected String doInBackground(Void... unused) {
loadingMore = true;
String result = null;
String url = "https://api.androidhive.info/json/imdb_top_250.php?offset=" + offset;
try {
URL mUrl = new URL(url);
HttpURLConnection urlConnection = (HttpURLConnection) mUrl.openConnection();
urlConnection.setConnectTimeout(10000); //set timeout to 5 seconds
urlConnection.connect();
InputStream inputStream = urlConnection.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
StringBuffer buffer = new StringBuffer();
String str = "";
while ((str = br.readLine()) != null) {
buffer.append(str);
}
result = buffer.toString();
} catch (Exception e) {
System.out.println("error " + e);
}
return result;
}
/*
* An InputStream that skips the exact number of bytes provided, unless it reaches EOF.
*/
public class FlushedInputStream extends FilterInputStream {
public FlushedInputStream(InputStream inputStream) {
super(inputStream);
}
@Override
public long skip(long n) throws IOException {
long totalBytesSkipped = 0L;
while (totalBytesSkipped < n) {
long bytesSkipped = in.skip(n - totalBytesSkipped);
if (bytesSkipped == 0L) {
int b = read();
if (b < 0) {
break; // we reached EOF
} else {
bytesSkipped = 1; // we read one byte
}
}
totalBytesSkipped += bytesSkipped;
}
return totalBytesSkipped;
}
}
public View getView(int position, View convertView, ViewGroup parent) {
View vi=convertView;
return vi;
}
protected void onPostExecute(String result) {
if (result != null) {
try {
JSONArray array = new JSONArray(result);
for (int i = 0; i < array.length(); i++) {
arrayList1.add(new SubjectData(array.getJSONObject(i).getString("title"),"link", "image"));
}
loadingMore = false;
System.out.println("to flag2 ine: "+ flag);
lv.invalidateViews();
// adapter1.updater(arrayList1);
offset+=20;
} catch (Exception e) {
e.printStackTrace();
}
} else {
if (pb==null)
{
System.out.println("ine null to pb ");
}
else if (lv==null) {
pb.setVisibility(pb.GONE);
Toast.makeText(getContext(), "Please check your internet connection!", Toast.LENGTH_SHORT).show();
pb=null;
}
else
{
lv.removeFooterView(pb);
}
}
}
}
}
And this is the customadapter that extends the baseadapter
public class CustomAdapter extends BaseAdapter {
public ArrayList<SubjectData> arrayList;
Context context;
Thread t;
public CustomAdapter(Context context, ArrayList<SubjectData> arrayList) {
this.context = context;
this.arrayList = arrayList;
}
public void updater(ArrayList<SubjectData> updatedlist)
{
this.arrayList.clear();
this.arrayList.addAll(updatedlist);
this.notifyDataSetChanged();
}
@Override
public boolean areAllItemsEnabled() {
return false;
}
@Override
public boolean isEnabled(int position) {
return true;
}
@Override
public int getCount() {
return arrayList.size();
}
@Override
public Object getItem(int position) {
return position;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public boolean hasStableIds() {
return false;
}
public View getView(int position, View convertView, ViewGroup parent) {
SubjectData subjectData = arrayList.get(position);
if(convertView == null) {
LayoutInflater layoutInflater = LayoutInflater.from(context);
convertView = layoutInflater.inflate(R.layout.listitem, null);
convertView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
AppCompatActivity activity= (AppCompatActivity)context;
ImageView image = new ImageView(context);
image.setImageResource(R.drawable.notificationstoreicon);
final ProgressBar pb = new ProgressBar(context);
String[] coupons = {"horse", "cow", "camel", "sheep", "goat"};
AlertDialog.Builder builder =
new AlertDialog.Builder(context).
setTitle("Details").
setView(pb).
setMessage("please wait...")
.
setPositiveButton("Go", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
})
.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// dialog.dismiss();
if (t.isAlive())
{
}
else
{
}
}
});
AlertDialog dialog1=builder.create();
dialog1.show();
t= new Thread()
{ private volatile boolean running = true;
public void run() {
System.out.println("blah");
while (running) {
try {
// thread to sleep for 1000 milliseconds
Thread.sleep(4000);
running=false;
} catch (Exception e) {
System.out.println(e);
}
}
runOnUiThread(new Runnable() {
@Override
public void run() {
dialog1.setMessage("more details");
pb.setVisibility(View.GONE);
Picasso.get()
.load(subjectData.Image)
.into(image);
dialog1.setContentView(image);
}
});
}
public void stopThread() {
running = false;
interrupt();
}
public void runOnUiThread(Runnable runnable){
final Handler UIHandler = new Handler(Looper.getMainLooper());
UIHandler.post(runnable);
}
};
t.start();
}
});
TextView tittle = convertView.findViewById(R.id.txt);
ImageView imag = convertView.findViewById(R.id.flagimageview);
tittle.setText(subjectData.SubjectName);
Picasso.get()
.load(subjectData.Image)
.into(imag);
}
return convertView;
}
@Override
public int getItemViewType(int position) {
return position;
}
@Override
public int getViewTypeCount() {
if(getCount() > 0){
return arrayList.size();
}else{
return 1;
}
}
@Override
public boolean isEmpty() {
return false;
}
}
Fragment home xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.home.HomeFragment">
<TextView
android:id="@+id/text_home"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:text="Please check your internet connection!"
android:textAlignment="center"
android:textSize="20sp"
android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:visibility="invisible" />
<ListView
android:id="@+id/homelistview"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/helloimageview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="productimage"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Any help appreciated. I searched in other people posts but no luck! I have been searching for hours actually!
Can anyone help me? Cant find solution!
invalidateViews
u only need to calladapter1.notifyDataSetChanged()
. Debug your code see if data is getting parsed and getting added in array List properly. – Extracanonicalwhen i call notifyDataSetChanged() it keeps triggering Oncreate from HomeFragment
. That should not happen its probably means Your app getting crashed . Check the Logs and add the error stacktrace with question. – Extracanonical