I'm trying to add ProgressBar to the bottom of the list while loading next page. How can do it? Is there a way to place my progressbar more efficiently? I saw many uses viewtype in adapter, but i don't really get how it changes. Also, after progressbar ended and new page added, i want the bottom item to scroll for 1 position below.
This is my list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="10dp"
android:orientation="vertical"
android:divider="#android:color/black">
<TextView
android:id="#+id/id"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginBottom="5dp"/>
<TextView
android:id="#+id/email"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"/>
<TextView
android:id="#+id/phone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_marginBottom="10dp"/>
</LinearLayout>
<ProgressBar
android:visibility="gone"
android:id="#+id/progressbar"
android:progress="1"
android:layout_width="100dp"
android:layout_height="100dp"
android:indeterminate="true"
android:layout_gravity="center_horizontal"/>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#ccc"/>
</android.support.v7.widget.CardView>
This is my MyAdapter.java
import android.app.Activity;
import android.content.Context;
import android.service.autofill.Dataset;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ProgressBar;
import java.util.ArrayList;
import java.util.HashMap;
public class MyAdapter extends RecyclerView.Adapter<MyViewHolder> {
Context c;
ArrayList<String> id;
ArrayList<String> name;
ArrayList<String> email;
ArrayList<String> phone;
private Activity mactivity;
private final int VIEW_TYPE_ITEM = 0;
private final int VIEW_TYPE_LOADING = 1;
private boolean isLoading;
private int visibleThreshold = 5;
private int lastVisibleItem, totalItemCount;
private OnLoadMoreListener onLoadMoreListener;
public interface OnLoadMoreListener {
void onLoadMore();
}
public MyAdapter(Context c, ArrayList<String> id, ArrayList<String> name, ArrayList<String> email, ArrayList<String> phone) {
this.c = c;
this.id = id;
this.name = name;
this.email= email;
this.phone = phone;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Log.d("viewType", "onCreateViewHolder: "+viewType);
View v = LayoutInflater.from(c).inflate(R.layout.list_item, parent, false);
return new MyViewHolder(v);
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.id.setText(id.get(position));
holder.name.setText(name.get(position));
holder.email.setText(email.get(position));
holder.phone.setText(phone.get(position));
}
#Override
public int getItemCount() {
return id.size();
}
}
This is my MainActivity.java
public class MainActivity extends AppCompatActivity {
private String URL = "myURL.php";
private String token = "mytoken";
RecyclerView mrecyclerView;
MyAdapter myAdapter;
ArrayList<String> id = new ArrayList<>();
ArrayList<String> name = new ArrayList<>();
ArrayList<String> email = new ArrayList<>();
ArrayList<String> phone = new ArrayList<>();
String next_page="";
ProgressBar mProgressBar;
private Parcelable recyclerViewState;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mProgressBar =(ProgressBar)findViewById(R.id.progressbar);
mrecyclerView = (RecyclerView) findViewById(R.id.mRecyclerview);
mrecyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this, LinearLayoutManager.VERTICAL, false));
new getJSON().execute();
myAdapter = new MyAdapter(getApplicationContext(), id, name, email, phone);
mrecyclerView.addOnScrollListener(new EndlessRecyclerOnScrollListener() {
#Override
public void onLoadMore() {
if (URL != null) {
//mProgressBar.setVisibility(View.VISIBLE);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
recyclerViewState = mrecyclerView.getLayoutManager().onSaveInstanceState();
URL = next_page;
new getJSON().execute();
}
}, 200);
//mProgressBar.setVisibility(View.GONE);
}
}
});
}
private class getJSON extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected void onPostExecute(Void v) {
super.onPostExecute(v);
mrecyclerView.getLayoutManager().onRestoreInstanceState(recyclerViewState);
mrecyclerView.setAdapter(myAdapter);
}
#Override
protected Void doInBackground(Void... voids) {
HTTPHandler httpHandler = new HTTPHandler();
String json = httpHandler.makeCall(URL, token);
if (json != null) {
try {
JSONObject jsonObject = new JSONObject(json);
JSONArray jsonArray = jsonObject.getJSONArray("data");
next_page = String.valueOf(jsonObject.get("next_page_url"));
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject obj = jsonArray.getJSONObject(i);
id.add(obj.getString("id"));
name.add(obj.getString("name"));
email.add(obj.getString("email"));
phone.add(obj.getString("phone"));
}
} catch (final JSONException e) {
Log.e("ERROR", "Json parsing error: " + e.getMessage());
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(),
"Json parsing error: " + e.getMessage(),
Toast.LENGTH_LONG)
.show();
}
});
}
} else {
Log.e("ERROR", "Couldn't get json from server.");
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(),
"Couldn't get json from server. Check LogCat for possible errors!",
Toast.LENGTH_LONG)
.show();
}
});
}
return null;
}
}
}
and i used EndlessRecyclerOnScrollListener.java from here
public abstract class EndlessRecyclerOnScrollListener extends RecyclerView.OnScrollListener {
// public static String TAG = EndlessRecyclerOnScrollListener.class.getSimpleName();
/**
* The total number of items in the dataset after the last load
*/
private int mPreviousTotal=0;
/**
* True if we are still waiting for the last set of data to load.
*/
private boolean mLoading = true;
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
int visibleItemCount = recyclerView.getChildCount();
int totalItemCount = recyclerView.getLayoutManager().getItemCount();
int firstVisibleItem = ((LinearLayoutManager) recyclerView.getLayoutManager()).findFirstVisibleItemPosition();
if (mLoading) {
if (totalItemCount > mPreviousTotal) {
mLoading = false;
mPreviousTotal = totalItemCount;
}
}
int visibleThreshold = 5;
if (!mLoading && (totalItemCount - visibleItemCount)
<= (firstVisibleItem + visibleThreshold)) {
// End has been reached
onLoadMore();
mLoading = true;
}
}
public abstract void onLoadMore();
}
This progressbar should be added in your activity's xml and not in list_item.xml but it is not.
So with this line in your activity class:
mProgressBar =(ProgressBar)findViewById(R.id.progressbar);
the variable mProgressBar is null because it cannot be found inside the activity's xml.
So move the below code from list_item.xml to activity_main.xml:
<ProgressBar
android:visibility="gone"
android:id="#+id/progressbar"
android:progress="1"
android:layout_width="100dp"
android:layout_height="100dp"
android:indeterminate="true"
android:layout_gravity="center_horizontal"/>
Related
How can I allow the user to filter their Contacts list using both text and numbers? This is such that the user can search for a contact based both on their names and phone number.
Below my current code for clarity:
#Override
public void onCreateOptionsMenu(final Menu menu, MenuInflater inflater) {
menu.clear(); // clears all menu items..
inflater.inflate(R.menu.options_menu_contacts, menu);
final MenuItem searchMenuItem = menu.findItem(R.id.search); // search option
SearchView mSearchView = (SearchView) searchMenuItem.getActionView();
// Set the filtering listener
mSearchView.setOnQueryTextListener(
new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
adapter.getFilter().filter(newText);
return false;
}
});
// TODO - hide the user card onSearch
// Needed to close the SearchView when pressing back (instead of just losing focus)
mSearchView.setOnQueryTextFocusChangeListener(
(v, hasFocus) -> {
// TODO - on focus change, show/hide user's card
if (!hasFocus) {
adapter.isSearchMode = false;
searchMenuItem.collapseActionView();
adapter.notifyDataSetChanged();
} else {
adapter.isSearchMode = true;
searchMenuItem.collapseActionView();
adapter.notifyDataSetChanged();
}
});
super.onCreateOptionsMenu(menu, inflater);
}
You can make a query on both the number as well as the contact name.
In your adapter:
public class Adapter extends RecyclerView.Adapter<Viewholder> implements Filterable {
private ArrayList<Contacts> contactArrayList = new ArrayList<>();
private ArrayList<Contacts> mFilteredList = new ArrayList<>();
private Context context;
...
#Override
public Filter getFilter() {
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence charSequence) {
String charString = charSequence.toString();
if (charString.isEmpty()) {
mFilteredList = contactArrayList;
} else {
ArrayList<Contacts> filteredList = new ArrayList<>();
for (Contacts contact : contactArrayList) {
if (contact.getNumber().toLowerCase().contains(charString.toLowerCase()) || events.getName().toLowerCase().contains(charString.toLowerCase())) {
filteredList.add(contact);
}
}
mFilteredList = filteredList;
}
FilterResults filterResults = new FilterResults();
filterResults.values = mFilteredList;
return filterResults;
}
#Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
mFilteredList = (ArrayList<Contacts>) filterResults.values;
notifyDataSetChanged();
}
};
}
}
MainActivity
package app.personal.sampleapp;
import android.content.ContentResolver;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.SearchView;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ListView;
import android.widget.ProgressBar;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity implements View.OnClickListener, View.OnFocusChangeListener, SearchView.OnQueryTextListener {
protected Toolbar toolbar;
private String id, name, phone, image_uri;
private byte[] contactImage = null;
private Bitmap bitmap;
private int queryLength;
private List<ContactItem> contactItems;
private ListView listView;
private ProgressBar progressBar;
private ContactAdapter adapter;
private SearchView searchView;
private MenuItem searchMenuItem;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
new ContactInfo().execute();
}
private void init() {
toolbar = (Toolbar) findViewById(R.id.tool_bar);
setSupportActionBar(toolbar);
listView = (ListView) findViewById(R.id.contact_list);
progressBar = (ProgressBar) findViewById(R.id.progress_bar);
}
private void readContacts() {
contactItems = new ArrayList<>();
ContentResolver cr = getApplicationContext().getContentResolver();
Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null,
null, null, null);
if (cur.getCount() > 0) {
while (cur.moveToNext()) {
ContactItem item = new ContactItem();
id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
name = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
name = Character.toUpperCase(name.charAt(0)) + name.substring(1);
image_uri = cur.getString(cur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.PHOTO_URI));
if (Integer.parseInt(cur.getString(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
Cursor pCur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", new String[]{id}, null);
while (pCur.moveToNext()) {
phone = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
phone = phone.replaceAll("\\s+", "");
phone = phone.replaceAll("[^0-9]", "");
}
pCur.close();
}
if (image_uri != null) {
try {
bitmap = MediaStore.Images.Media
.getBitmap(getApplicationContext().getContentResolver(),
Uri.parse(image_uri));
contactImage = getImageBytes(bitmap);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} else {
contactImage = null;
}
item.setId(id);
item.setName(name);
item.setContactImage(contactImage);
item.setPhone(phone);
contactItems.add(item);
}
}
}
private byte[] getImageBytes(Bitmap bitmap) {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
return outputStream.toByteArray();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_search, menu);
searchView = (SearchView) menu.findItem(R.id.search).getActionView();
searchMenuItem = menu.findItem(R.id.search);
searchView.setQueryHint(getResources().getString(R.string.type_here));
searchView.setOnQueryTextFocusChangeListener(this);
searchView.setOnQueryTextListener(this);
return super.onCreateOptionsMenu(menu);
}
#Override
public void onClick(View v) {
}
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus) {
searchMenuItem.collapseActionView();
searchView.setQuery("", false);
}
}
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
queryLength = newText.length();
adapter.getFilter().filter(newText);
return false;
}
public class ContactInfo extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
progressBar.setVisibility(View.VISIBLE);
listView.setVisibility(View.GONE);
}
#Override
protected Void doInBackground(Void... params) {
readContacts();
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
progressBar.setVisibility(View.GONE);
listView.setVisibility(View.VISIBLE);
setListAdapter();
}
}
private void setListAdapter() {
adapter = new ContactAdapter(getApplicationContext(), contactItems);
listView.setAdapter(adapter);
}
}
Create your customAdapter class:
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
public class ContactAdapter extends ArrayAdapter<ContactItem> implements Filterable {
private Context context;
private List<ContactItem> contacts, filterList;
private LayoutInflater inflater;
private ContactFilter filter;
public ContactAdapter(Context context, List<ContactItem> contacts) {
super(context, R.layout.contact_row, contacts);
this.contacts = contacts;
this.context = context;
filterList = new ArrayList<>();
this.filterList.addAll(contacts);
}
#Override
public Filter getFilter() {
if (filter == null)
filter = new ContactFilter();
return filter;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view;
ViewHolder viewHolder = new ViewHolder();
if (convertView == null) {
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.contact_row, parent, false);
} else {
view = convertView;
}
viewHolder.name = (TextView) view.findViewById(R.id.name);
viewHolder.photo = (ImageView) view.findViewById(R.id.photo);
viewHolder.number = (TextView) view.findViewById(R.id.phone);
viewHolder.name.setText(contacts.get(position).getName());
viewHolder.number.setText(contacts.get(position).getPhone());
if ((contacts.get(position).getContactImage()) != null) {
Bitmap contactImage = getContactImage(contacts.get(position).getContactImage());
viewHolder.photo.setImageBitmap(contactImage);
}else {
viewHolder.photo.setImageResource(R.drawable.dummy_icon);
}
return view;
}
private Bitmap getContactImage(byte[] photo) {
int targetW = 50, targetH = 50;
BitmapFactory.Options options = new BitmapFactory.Options();
BitmapFactory.decodeByteArray(photo, 0, photo.length, options);
options.inJustDecodeBounds = true;
int imageW = options.outWidth;
int imageH = options.outHeight;
int scaleFactor = 1;
if ((targetW > 0) || (targetH > 0)) {
scaleFactor = Math.min(imageW / targetW, imageH / targetH);
}
options.inJustDecodeBounds = false;
options.inSampleSize = scaleFactor;
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
return BitmapFactory.decodeByteArray(photo, 0, photo.length, options);
}
public class ViewHolder {
ImageView photo;
TextView name, number;
}
private class ContactFilter extends Filter {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
String data = constraint.toString().toLowerCase();
FilterResults results = new FilterResults();
if (data.length() > 0) {
List<ContactItem> filteredList = new ArrayList<>(filterList);
List<ContactItem> nList = new ArrayList<>();
int count = filteredList.size();
for (int i = 0; i < count; i++) {
ContactItem item = filteredList.get(i);
String name = item.getName().toLowerCase();
String phone = item.getPhone().toLowerCase();
if (name.startsWith(data) || phone.startsWith(data))
nList.add(item);
}
results.count = nList.size();
results.values = nList;
} else {
List<ContactItem> list = new ArrayList<>(filterList);
results.count = list.size();
results.values = list;
}
return results;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
contacts = (ArrayList<ContactItem>) results.values;
clear();
for (int i = 0; i < contacts.size(); i++) {
ContactItem item = (ContactItem) contacts.get(i);
add(item);
notifyDataSetChanged();
}
}
}
#Override
public void notifyDataSetChanged() {
super.notifyDataSetChanged();
}
}
Create POJO Class
public class ContactItem {
private String id, name, phone;
private byte[] contactImage = null;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public byte[] getContactImage() {
return contactImage;
}
public void setContactImage(byte[] contactImage) {
this.contactImage = contactImage;
}
}
MainActivity.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<FrameLayout
android:id="#+id/frame_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true">
<include
android:id="#+id/tool_bar"
layout="#layout/toolbar" />
</FrameLayout>
<ListView
android:id="#+id/contact_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/frame_toolbar"
android:cacheColorHint="#android:color/transparent"
android:clipToPadding="false"
android:divider="#null"
android:dividerHeight="1dp"
android:listSelector="#android:color/transparent" />
<ProgressBar
android:id="#+id/progress_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true" />
</RelativeLayout>
Create row Item layout file:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="#FFF"
android:orientation="horizontal">
<ImageView
android:id="#+id/photo"
android:layout_width="50dp"
android:layout_height="50dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:weightSum="1">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="#+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="15dp"
android:textColor="#000000"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:id="#+id/phone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="15dp"
android:layout_marginTop="5dp"
android:textColor="#000000"
android:textSize="14sp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
toolbar.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#f57c00"
app:theme="#style/ThemeOverlay.AppCompat.Dark" />
Create menu_search.xml in menu folder:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/search"
android:icon="#drawable/search"
android:title="#string/search_view"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="collapseActionView|always" />
</menu>
add below code in style.xml file:
<style name="NoActionBar" parent="Theme.AppCompat.Light.NoActionBar">
<item name="actionOverflowMenuStyle">#style/PopupMenu</item>
</style>
<style name="PopupMenu" parent="Widget.AppCompat.PopupMenu.Overflow">
<item name="android:textColor">#FFF</item>
</style>
add below code in AndroidManifest.xml:
android:theme="#style/NoActionBar" // add in application theme
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
I want to ask you, how to change programmatically the background color of LinearLayout in CardView when the text in TextView equals specify word or is empty. For example field1 getting string "red", the background of LinearLayout gets red. I'm fetching the data from JSON php file.
MainActivity.class
public class MainActivity extends AppCompatActivity {
private String jsonURL = "http://example.com/test.php";
private final int jsoncode = 1;
private RecyclerView recyclerView;
ArrayList<Model> ModelArrayList;
private Adapter adapter;
private static ProgressDialog mProgressDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = findViewById(R.id.recycler);
fetchJSON();
}
#SuppressLint("StaticFieldLeak")
private void fetchJSON(){
new AsyncTask<Void, Void, String>(){
protected String doInBackground(Void[] params) {
String response="";
HashMap<String, String> map=new HashMap<>();
try {
HttpRequest req = new HttpRequest(jsonURL);
response = req.prepare(HttpRequest.Method.POST).withData(map).sendAndReadString();
} catch (Exception e) {
response=e.getMessage();
}
return response;
}
protected void onPostExecute(String result) {
//do something with response
onTaskCompleted(result,jsoncode);
}
}.execute();
}
public void onTaskCompleted(String response, int serviceCode) {
Log.d("responsejson", response.toString());
switch (serviceCode) {
case jsoncode:
if (isSuccess(response)) {
removeSimpleProgressDialog(); //will remove progress dialog
ModelArrayList = getInfo(response);
adapter = new Adapter(this,ModelArrayList);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext(), LinearLayoutManager.VERTICAL, false));
}else {
Toast.makeText(MainActivity.this, getErrorCode(response), Toast.LENGTH_SHORT).show();
}
}
}
public ArrayList<Model> getInfo(String response) {
ArrayList<Model> ModelArrayList = new ArrayList<>();
try {
JSONObject jsonObject = new JSONObject(response);
if (jsonObject.getString("status").equals("true")) {
JSONArray dataArray = jsonObject.getJSONArray("data");
for (int i = 0; i < dataArray.length(); i++) {
Model fieldsModel = new Model();
JSONObject dataobj = dataArray.getJSONObject(i);
fieldsModel.setField1(dataobj.getString("field1"));
fieldsModel.setField2(dataobj.getString("field2"));
ModelArrayList.add(fieldsModel);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
return ModelArrayList;
}
public boolean isSuccess(String response) {
try {
JSONObject jsonObject = new JSONObject(response);
if (jsonObject.optString("status").equals("true")) {
return true;
} else {
return false;
}
} catch (JSONException e) {
e.printStackTrace();
}
return false;
}
public String getErrorCode(String response) {
try {
JSONObject jsonObject = new JSONObject(response);
return jsonObject.getString("message");
} catch (JSONException e) {
e.printStackTrace();
}
return "No data";
}
}
Adapter.class
public class Adapter extends RecyclerView.Adapter<Adapter.MyViewHolder> {
private LayoutInflater inflater;
private ArrayList<Model> ModelArrayList;
public Adapter(Context ctx, ArrayList<Model> rogerModelArrayList){
inflater = LayoutInflater.from(ctx);
this.ModelArrayList = rogerModelArrayList;
}
#Override
public Adapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.rv_item, parent, false);
MyViewHolder holder = new MyViewHolder(view);
return holder;
}
#Override
public void onBindViewHolder(Adapter.MyViewHolder holder, int position) {
holder.field1.setText(ModelArrayList.get(position).getField1());
holder.field2.setText(ModelArrayList.get(position).getField2());
}
#Override
public int getItemCount() {
return ModelArrayList.size();
}
class MyViewHolder extends RecyclerView.ViewHolder{
TextView field1,field2;
public MyViewHolder(View itemView) {
super(itemView);
field1 = (TextView) itemView.findViewById(R.id.field1);
field2 = (TextView) itemView.findViewById(R.id.field2);
}
}
}
Model.class
public class Model {
private String field1, field2;
public String getField1() {
return field1;
}
public void setField1(String field1) {
this.field1 = field1;
}
public String getField2() {
return field2;
}
public void setField2(String field2) {
this.field2 = field2;
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:orientation="vertical"
android:background="#cd15e6"
tools:context=".MainActivity">
** <android.support.v7.widget.RecyclerView
android:id="#+id/recycler"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:layout_marginTop="15dp"/> **
</LinearLayout>
rv_item.xml
Here is the LinearLayout which i want to change the color LL_background
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.CardView
android:id="#+id/card_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
app:cardCornerRadius="5dp">
<LinearLayout
android:id="#+id/LL_background"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="100dp"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:orientation="vertical">
<TextView
android:id="#+id/field1"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_marginTop="5dp"
android:layout_weight="1"
android:text="ddd"
android:textColor="#000"
android:textStyle="bold" />
<TextView
android:id="#+id/field2"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:text="ddd"
android:textColor="#000"
android:textStyle="bold" />
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
Please check my project and share your ideas. Thanks a lot 😊
First of all add layout reference to ViewHolder
class MyViewHolder extends RecyclerView.ViewHolder{
TextView field1,field2;
LinearLayout layout;
public MyViewHolder(View itemView) {
super(itemView);
field1 = (TextView) itemView.findViewById(R.id.field1);
field2 = (TextView) itemView.findViewById(R.id.field2);
layout = itemView.findViewById(R.id.LL_background);
}
}
Then check Field1 and set color
#Override
public void onBindViewHolder(Adapter.MyViewHolder holder, int position) {
holder.field1.setText(ModelArrayList.get(position).getField1());
holder.field2.setText(ModelArrayList.get(position).getField2());
if(ModelArrayList.get(position).getField1().equalIgnoreCase("red")
holder.layout.setBackgroundColor(Color.RED)
}
red is not recognizable in android. Either you have to handle it manually like above or you can send the corresponding #code of color from server and handle it like below:
holder.layout.setBackgroundColor(Color.parseColor("#ff0000"));
You can change layout instead color. Create different layouts that has different background color or different design. Then do this.
#Override
public Adapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.rv_item, parent, false);
if(ModelArrayList.get(position).getField1().equalIgnoreCase("red")
view = inflater.inflate(R.layout.anotherLayout, parent, false);
MyViewHolder holder = new MyViewHolder(view);
return holder;
}
I am trying to make an Activity which will hold all the recents screen in my app not in the android device.
The idea it is to create the recents view like in android.
I do not have for the moment an idea how to do that. I have searched in the official site of android but didn't get what I want.
I have some activities which there is declared WebView and I want to take title, url and the view of that Url and to save to show at VisualHistory.
The design I am able to do I have achieved but I do not know how to show the recents screen or views.
The color of the background should based from url.
If someone don't understand something let me know.
Below you can find a photo which will show what I am trying to do, I have copied this photo from another app.
I have planned these steps to follow to achieve that.
In the Pojo.class and in db it is not defined the image which will be shown in the cardview because I do not know how to achieve that.
I want the background which for the moment in blue to be depended from the url color. Is it any way to get the color of the url ?
Create a POJO.class
Create a DB which will hold this data
Create an Adapter
Create a Fragment
I have a Log here which shows me the items.
[VisualHistoryItem{id=109, title='Wikipedia, the free encyclopedia', url='https://en.m.wikipedia.org/w/index.php?title=Main_Page'}, VisualHistoryItem{id=112, title='', url='https://mail.google.com/'}, VisualHistoryItem{id=113, title='Gmail – kostenloser Speicherplatz und E-Mails von Google', url='https://www.google.com/intl/de/gmail/about/#'}]
This saves a visual history item.
mVisualHistory.setUrl(url);
mVisualHistory.setTitle(view.getTitle());
Bitmap topass= getSnapshoot.takeScreenShot(BookmarkActivity.this);
try {
String filename = mVisualHistory.getId()+".png";
FileOutputStream stream = BookmarkActivity.this.openFileOutput(filename, Context.MODE_PRIVATE);
topass.compress(Bitmap.CompressFormat.PNG, 100, stream);
stream.close();
topass.recycle();
} catch (Exception e) {
e.printStackTrace();
}
mVisualRepository.insertNoteTask(mVisualHistory);
I have created an Activity code is below.
public class ActivityTabs extends AppCompatActivity implements View.OnClickListener {
private PopupMenu mPopupMenu;
private FrameLayout settings;
private FrameLayout frameLayout;
private LinearLayout linearLayout;
private ImageView incognito;
private TextView textOfHistory;
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tabs);
findViewById(R.id.vgGoMain).setOnClickListener(this);
findViewById(R.id.vgAdd).setOnClickListener(this);
settings = findViewById(R.id.vgSettingsHis);
linearLayout = findViewById(R.id.layoutEmptyVisHistory);
settings.setOnClickListener(this);
textOfHistory = findViewById(R.id.tvEmptyHistory);
FragmentVisualHistoryVertical newFragment = new FragmentVisualHistoryVertical();
getSupportFragmentManager().beginTransaction().add(R.id.frameLayoutVisHistory, newFragment).commit();
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.frameLayoutVisHistory, newFragment)
.commit();
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.vgGoMain:
finish();
return;
case R.id.vgAdd:
Intent intent = new Intent(this, ActivitySearchEngine.class);
startActivity(intent);
finish();
return;
case R.id.vgSettingsHis:
showMenuSettings();
return;
default:
break;
}
}
public void showMenuSettings() {
mPopupMenu = new PopupMenu(this, settings);
final MenuInflater menuInflater = mPopupMenu.getMenuInflater();
menuInflater.inflate(R.menu.history_settings, mPopupMenu.getMenu());
mPopupMenu.show();
}
}
And this is the XML for this Activity.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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="fill_parent"
android:layout_height="fill_parent"
android:background="#color/historyEmptyBack"
android:gravity="center_horizontal"
android:orientation="vertical">
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<FrameLayout
android:id="#+id/frameLayoutVisHistory"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:paddingBottom="#dimen/bottomPanelHeight"></FrameLayout>
<LinearLayout
android:id="#+id/layoutEmptyVisHistory"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:visibility="gone">
<TextView
android:id="#+id/tvEmptyHistoryTitle"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="#dimen/common_24dp"
android:gravity="center_horizontal"
android:lineSpacingExtra="3.0sp"
android:text="#string/VHVEmptyTite"
android:textColor="#color/historyEmptyTitle"
android:textSize="22.0sp" />
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginBottom="48.0dip"
android:layout_weight="1.0">
<LinearLayout
android:id="#+id/horizontalEmpty"
style="#style/LayoutEmptySmile"
android:layout_width="#dimen/visual_history_element_width"
android:layout_height="#dimen/visual_history_element_height"
android:orientation="vertical">
<ImageView
style="#style/EmptyHistorySmile"
android:src="#drawable/vh_smile_gray" />
<TextView
style="#style/EmptyHistoryText"
android:layout_marginTop="#dimen/common_16dp"
android:gravity="center_horizontal"
android:paddingLeft="#dimen/common_16dp"
android:paddingRight="#dimen/common_16dp"
android:text="#string/VHVEmptyDesc" />
</LinearLayout>
<LinearLayout
android:id="#+id/verticalEmpty"
style="#style/LayoutEmptySmile"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="#dimen/common_24dp"
android:layout_marginRight="#dimen/common_24dp"
android:orientation="horizontal"
android:paddingLeft="#dimen/common_16dp"
android:paddingTop="#dimen/common_16dp"
android:paddingRight="#dimen/common_16dp"
android:paddingBottom="#dimen/common_16dp">
<ImageView
style="#style/EmptyHistorySmile"
android:src="#drawable/vh_smile_gray" />
<TextView
style="#style/EmptyHistoryText"
android:layout_width="wrap_content"
android:gravity="left"
android:paddingLeft="#dimen/common_16dp"
android:text="#string/VHVEmptyDesc" />
</LinearLayout>
<LinearLayout
android:id="#+id/layoutIncognito"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:paddingBottom="#dimen/bottomPanelHeight"
android:visibility="visible">
<LinearLayout
android:id="#+id/layoutEmptyDesc"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginTop="#dimen/common_16dp"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:id="#+id/ivEmptyHistory"
android:layout_width="#dimen/history_private"
android:layout_height="#dimen/history_private"
android:src="#drawable/incognito_icon_history" />
<TextView
android:id="#+id/tvEmptyHistory"
style="#style/EmptyHistoryText"
android:layout_marginTop="#dimen/common_16dp"
android:gravity="center_horizontal"
android:paddingLeft="#dimen/common_16dp"
android:paddingRight="#dimen/common_16dp"
android:text="#string/SVSearchPrivateMode"
android:textColor="#color/historyTextColor"
android:textSize="#dimen/common_18sp" />
</LinearLayout>
</LinearLayout>
</FrameLayout>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="#color/historyEmptyBack"
android:gravity="bottom"
android:orientation="vertical"
android:paddingLeft="2.0dip"
android:paddingRight="2.0dip">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">
<LinearLayout style="#style/VisHistoryMenuSideLayout">
<FrameLayout
android:id="#+id/vgGoMain"
style="#style/VisHistoryFrLayoutMenu"
android:paddingRight="14.0dip">
<TextView
style="#style/VisHistoryTvMenu"
android:text="#string/VHVHomeBarButtonItemTitle" />
</FrameLayout>
<View style="#style/VisHistoryEmptyView" />
</LinearLayout>
<FrameLayout
android:id="#+id/vgAdd"
style="#style/VisHistoryFrLayoutMenu">
<ImageView
style="#style/VisHistoryMenuIv"
android:scaleX="0.8"
android:scaleY="0.8"
android:src="#drawable/newtab_button" />
</FrameLayout>
<LinearLayout style="#style/VisHistoryMenuSideLayout">
<View style="#style/VisHistoryEmptyView" />
<FrameLayout
android:id="#+id/vgTrash"
style="#style/VisHistoryFrLayoutMenu">
<ImageView
style="#style/VisHistoryMenuIv"
android:scaleX="1.3"
android:scaleY="1.3"
android:src="#drawable/trash" />
</FrameLayout>
<View style="#style/VisHistoryEmptyView" />
<FrameLayout
android:id="#+id/vgSettingsHis"
style="#style/VisHistoryFrLayoutMenu"
android:paddingLeft="0.0dip"
android:paddingRight="0.0dip">
<android.support.v7.widget.AppCompatImageView
style="#style/VisHistoryMenuIv"
android:layout_gravity="right"
app:srcCompat="#drawable/ic_dots_vertical"
tools:ignore="VectorDrawableCompat" />
</FrameLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</FrameLayout>
</LinearLayout>
This is another Fragment
Here will show of the list
public class FragmentVisualHistoryVertical extends FragmentVisualHistory implements VisualRecyclerAdapter.OnVisualHistoryItemListener {
public View paramView;
private VisualRecyclerAdapter mVisualHistoryRecyclerAdapter;
private RecyclerView mRecyclerView;
private VisualHistoryRepository getmNoteRepository;
private ArrayList<VisualHistoryItem> mVisualHistoryItems = new ArrayList<>();
#Override
public void onAttach(Context context) {
super.onAttach(context);
mContext = context;
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
paramView = inflater.inflate(R.layout.fragment_vis_history_vertical, container, false);
mRecyclerView = paramView.findViewById(R.id.rvWebHistory);
initRecyclerView();
getmNoteRepository = new VisualHistoryRepository(getActivity());
retrieveVisualHistory();
return paramView;
}
private void initRecyclerView(){
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
mRecyclerView.setLayoutManager(linearLayoutManager);
linearLayoutManager.setReverseLayout(true);
new ItemTouchHelper(itemTouchHelperCallback).attachToRecyclerView(mRecyclerView);
mVisualHistoryRecyclerAdapter = new VisualRecyclerAdapter(mVisualHistoryItems, this, mContext);
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView.getContext(),
linearLayoutManager.getOrientation());
mRecyclerView.addItemDecoration(dividerItemDecoration);
mRecyclerView.setAdapter(mVisualHistoryRecyclerAdapter);
}
private void retrieveVisualHistory() {
getmNoteRepository.retrieveVisualHistoryTask().observe(this, new Observer<List<VisualHistoryItem>>() {
#Override
public void onChanged(#Nullable List<VisualHistoryItem> item) {
if(mVisualHistoryItems.size() > 0){
mVisualHistoryItems.clear();
}
if(item != null){
mVisualHistoryItems.addAll(item);
}
mVisualHistoryRecyclerAdapter.notifyDataSetChanged();
}
});
}
#Override
public void onItemClicked(int position) {
}
private void deleteNote(VisualHistoryItem item) {
mVisualHistoryItems.remove(item);
mVisualHistoryRecyclerAdapter.notifyDataSetChanged();
getmNoteRepository.deleteVisualHistoryTask(item);
}
ItemTouchHelper.SimpleCallback itemTouchHelperCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.RIGHT) {
#Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
return false;
}
#Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
deleteNote(mVisualHistoryItems.get(viewHolder.getAdapterPosition()));
}
};
}
This is the XML.
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:aapt="http://schemas.android.com/aapt" android:id="#+id/rvWebHistory" android:layout_width="match_parent" android:layout_height="match_parent"/>
This is the room db
#Database(entities = {VisualHistoryItem.class}, version = 1)
public abstract class VisualHistoryDB extends RoomDatabase {
private static final String DATABASE_NAME = "visualHistory_db";
private static VisualHistoryDB instance;
public static VisualHistoryDB getInstance(final Context context) {
if (instance == null) {
instance = Room.databaseBuilder(
context.getApplicationContext(),
VisualHistoryDB.class,
DATABASE_NAME
).build();
}
return instance;
}
public abstract VisualHistoryDao getVisualHistoryDao();
}
The room db Dao
#Dao
public interface VisualHistoryDao {
#Insert
long[] insertVisualHistory(VisualHistoryItem... visualHistoryItems);
#Query("SELECT * FROM visualHistory")
LiveData<List<VisualHistoryItem>> getVisualHistory();
#Delete
int delete(VisualHistoryItem... visualHistoryItems);
}
This is the pojo.class
#Entity(tableName = "visualHistory")
public class VisualHistoryItem implements Parcelable {
#PrimaryKey(autoGenerate = true)
private int id;
#ColumnInfo(name = "title")
private String title;
#ColumnInfo(name = "url")
private String url;
public VisualHistoryItem(int id, String title, String url) {
this.id = id;
this.title = title;
this.url = url;
}
#Ignore
public VisualHistoryItem() {
}
protected VisualHistoryItem(Parcel in) {
id = in.readInt();
title = in.readString();
url = in.readString();
}
public static final Creator<VisualHistoryItem> CREATOR = new Creator<VisualHistoryItem>() {
#Override
public VisualHistoryItem createFromParcel(Parcel in) {
return new VisualHistoryItem(in);
}
#Override
public VisualHistoryItem[] newArray(int size) {
return new VisualHistoryItem[size];
}
};
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
#Override
public String toString() {
return "VisualHistoryItem{" +
"id=" + id +
", title='" + title + '\'' +
", url='" + url + '\'' +
'}';
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeInt(id);
parcel.writeString(title);
parcel.writeString(url);
}
}
And this is the Adapter.
public class VisualRecyclerAdapter extends RecyclerView.Adapter<VisualRecyclerAdapter.ViewHolder> {
private ArrayList<VisualHistoryItem> mVisualHistoryItem = new ArrayList<>();
private OnVisualHistoryItemListener mItemListener;
private final Context context;
public VisualRecyclerAdapter(ArrayList<VisualHistoryItem> mVisualHistoryItem, OnVisualHistoryItemListener mItemListener, Context context) {
this.context = context;
this.mVisualHistoryItem = mVisualHistoryItem;
this.mItemListener = mItemListener;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.fragment_visual_history, viewGroup, false);
return new ViewHolder(view, mItemListener);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder viewHolder, int i) {
Resources res = viewHolder.itemView.getContext().getResources();
viewHolder.visFragmentMain.setBackgroundColor(res.getColor(R.color.blue_text));
viewHolder.tvPageUrl.setText(mVisualHistoryItem.get(i).getUrl());
viewHolder.tvPageName.setText(mVisualHistoryItem.get(i).getTitle());
Bitmap bmp = null;
String filename = mVisualHistoryItem.get(i).getId()+".png";
try {
FileInputStream is = context.openFileInput(filename);
bmp = BitmapFactory.decodeStream(is);
is.close();
} catch (Exception e) {
e.printStackTrace();
}
if (bmp!=null) {
BitmapDrawable ob = new BitmapDrawable(context.getResources(), bmp);
viewHolder.ivVisualHistory.setBackground(ob);
}
}
#Override
public int getItemCount() {
return mVisualHistoryItem.size();
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
ImageView ivVisualHistory;
OnVisualHistoryItemListener itemListener;
TextView tvPageName, tvPageUrl;
RelativeLayout visFragmentMain;
CardView cardView;
public ViewHolder(#NonNull View itemView, OnVisualHistoryItemListener mItemListener) {
super(itemView);
itemListener = mItemListener;
ivVisualHistory = itemView.findViewById(R.id.ivVisualHistory);
visFragmentMain = itemView.findViewById(R.id.visFragmentMain);
tvPageName = itemView.findViewById(R.id.tvPageName);
tvPageUrl = itemView.findViewById(R.id.tvPageUrl);
cardView = itemView.findViewById(R.id.cardView);
}
#Override
public void onClick(View v) {
itemListener.onItemClicked(getAdapterPosition());
}
}
public interface OnVisualHistoryItemListener {
void onItemClicked(int position);
}
}
This is what I am trying to achieve.
This is my actual view.
Well you can get the favicon of the website and use the Palette class of android explained here to get the prominent color of the url and if you want to get the snapshot you can save the snapshot and save instance data before launching another activity. To take snapshot you can use takesnapshot meathod after creating util class, code as follows:
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.view.View;
class Util {
static Bitmap takeScreenShot(Activity activity) {
View view = activity.getWindow().getDecorView();
view.setDrawingCacheEnabled(true);
view.buildDrawingCache();
Bitmap b1 = view.getDrawingCache();
Rect frame = new Rect();
activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
int statusBarHeight = frame.top;
//Find the screen dimensions to create bitmap in the same size.
int width = activity.getWindowManager().getDefaultDisplay().getWidth();
int height = activity.getWindowManager().getDefaultDisplay().getHeight();
Bitmap b = Bitmap.createBitmap(b1, 0, statusBarHeight, width, height - statusBarHeight);
view.destroyDrawingCache();
return b;
}
}
in your activity use it to save it to png file as follows:
Bitmap topass=Util.takeScreenShot(this);
try {
//Write file
String filename = "bitmap.png";
FileOutputStream stream = this.openFileOutput(filename, Context.MODE_PRIVATE);
topass.compress(Bitmap.CompressFormat.PNG, 100, stream);
//Cleanup
stream.close();
topass.recycle();
} catch (Exception e) {
e.printStackTrace();
}
Instead of using name "bitmap.png" use your "id.png"(String.valueof(id)+".png") as you have put int "id" name in your db. You can save screenshot of every activity with its id and whenever you build the cardview of it, show the screenshot by the name of "id.png". To show screenshot, you can use
Bitmap bmp = null;
String filename = String.valueof(getId())+".png";
try {
FileInputStream is = this.openFileInput(filename);
bmp = BitmapFactory.decodeStream(is);
is.close();
} catch (Exception e) {
e.printStackTrace();
}
if(bmp!=null)
{
ConstraintLayout cl =findViewById(R.id.shopbk); //it can be your any view
BitmapDrawable ob = new BitmapDrawable(getResources(), bmp);
cl.setBackground(ob); /* you should use glide here to show bitmap drawable as your preview will be very small as compared to screenshot actual size*/
}
and as far as getting the color (you said the link is not working) is concerned you can get firstly the bitmap using
try {
URL url = new URL("http://..somepath url../favicon.ico");
Bitmap image = BitmapFactory.decodeStream(url.openConnection().getInputStream());
} catch(IOException e) {
System.out.println(e);
}
and then use palette to extract the color using
Palette.generateAsync(image, new Palette.PaletteAsyncListener() {
public void onGenerated(Palette palette) {
// Do something with colors...
}
});
for this you will need to implement one dependancy
dependencies {
...
compile 'com.android.support:palette-v7:21.0.+'
}
I want to know what is the best way to use a Asynctask class(LocationAsyncTask.java) with an Activity to change UI data(ListView).
I have this exception error:
Error:(40, 5) error: method does not override or implement a method from a supertype
EDITED:
I have this Asynctask class(LocationAsyncTask.java):
public abstract class LocationAsyncTask extends AsyncTask{
public ArrayList<Location> locationList;
public Context context;
public LocationAsyncTask(Context context) {
this.context = context;
}
#Override
protected Object doInBackground(Object[] objects) {
try {
//These lines are an example(I will obtain the data via internet)
Location ejemplo = new Location("Locality1","name","address");
Location ejemplo2 = new Location("Locality2","name2","address2");
locationList = new ArrayList<Location>();
locationList.add(ejemplo);
locationList.add(ejemplo2);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {}
}
And this is my Activity class:
public class LocationNativeActivity extends Activity {
ArrayList<Location> locationList;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LocationAsyncTask myTask = new LocationAsyncTask(this){
#Override
protected void onPostExecute(Void aVoid) {
ListView s = (ListView)(findViewById(R.id.lvlocationnative));
ArrayAdapter<Location> adapter = new ArrayAdapter<Location>(context, android.R.layout.simple_list_item_1, locationList);
s.setAdapter(adapter);
}
};
myTask.execute();
}
}
And this is my layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="#+id/lvlocationnative"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
This is my Location class:
public class Location {
private String addressLocality;
private String name;
private String address;
public Location(String addressLocality,String name, String address) {
this.addressLocality = addressLocality;
this.name = name;
this.address = address;
}
public String getAddressLocality() {
return addressLocality;
}
public void setAddressLocality(String addressLocality) {
this.addressLocality = addressLocality;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
#Override
public String toString() {
return this.addressLocality;
}
}
With this code I can not insert data in the Listview, any suggestions?
I check these post:
https://stackoverflow.com/a/15409989/3739382
https://stackoverflow.com/a/35193172/3739382
There are plenty of issues with your approach and #Jyoti has just highlighted one of them. You cannot simply use ArrayAdapter as it is with complex object. It won't yield useful results. Instead you need to create CustomAdapter.
Create Custom Item view lets say item_location.xml under layout folder and put following code:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent" >
<TextView
android:id="#+id/tvaddressLocality"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="bold"
android:text="Address Locality" />
<TextView
android:id="#+id/tvName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Name" />
<TextView
android:id="#+id/tvAddress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Address" /></LinearLayout>
Create CustomAdapter class as follows:
import android.content.Context;
import android.support.annotation.NonNull;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import java.util.ArrayList;
public class CustomLocationAdapter extends ArrayAdapter<Location> {
public CustomLocationAdapter(#NonNull Context context, ArrayList<Location> locations) {
super(context,0, locations);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// Get the data item for this position
Location location = getItem(position);
// Check if an existing view is being reused, otherwise inflate the view
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.item_location, parent, false);
}
// Lookup view for data population
TextView tvAddressLocality = (TextView) convertView.findViewById(R.id.tvaddressLocality);
TextView tvName = (TextView) convertView.findViewById(R.id.tvName);
TextView tvAddress = (TextView) convertView.findViewById(R.id.tvAddress);
// Populate the data into the template view using the data object
tvAddressLocality.setText(location.getAddressLocality());
tvName.setText(location.getName());
tvAddress.setText(location.getAddress());
// Return the completed view to render on screen
return convertView;
}
}
Update your LocationAsyncTask as follows:
public class LocationAsyncTask extends AsyncTask {
private ArrayList<Location> locationList;
private final WeakReference<ListView> listViewWeakReference;
private Context context;
public LocationAsyncTask(ListView listView, Context context) {
this.listViewWeakReference = new WeakReference<>(listView);
this.context = context;
}
#Override
protected Object doInBackground(Object[] objects) {
try {
//These lines are an example(I will obtain the data via internet)
Location ejemplo = new Location("Locality1s", "name", "address");
Location ejemplo2 = new Location("Locality2", "name2", "address2");
locationList = new ArrayList<Location>();
locationList.add(ejemplo);
locationList.add(ejemplo2);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Object o) {
super.onPostExecute(o);
ArrayAdapter<Location> adapter = new CustomLocationAdapter(context, locationList);
listViewWeakReference.get().setAdapter(adapter);
}
}
Update you LocationNativeActivity.onCreate() as follows:
ListView listView = LocationNativeActivity.this.findViewById(R.id.lvlocationnative);
LocationAsyncTask myTask = new LocationAsyncTask(listView, this);
myTask.execute();
You can replace your code:
LocationAsyncTask myTask = new LocationAsyncTask(this);
as:
LocationAsyncTask myTask = new LocationAsyncTask(this){
#Override
protected void onPostExecute(Void aVoid) {
ListView s = (ListView)(findViewById(R.id.lvlocationnative));
ArrayAdapter<Location> adapter = new ArrayAdapter<Location>(context, android.R.layout.simple_list_item_1, locationList);
s.setAdapter(adapter);
}
};
In your Async task:
Make the arrayList as public
Use this onPostExecute() method:
protected void onPostExecute(Void aVoid) {}
This question already has answers here:
findViewByID returns null
(33 answers)
Closed 6 years ago.
Im trying to use intent to get information from the textview in my listview and display it on another activity. I have tried searching for answers but i cant seem to find the problem .
Menuactivity :
public class MenuActivity extends Activity {
private String server = "http://172.16.156.56";
private String sql_table = "orders";
private ListView list;
private TextView txtOrder, txtMember, txtPrice;
private Button btnAdd;
ArrayList<String> rows;
ListView listView1;
Button btnSubmit;
ArrayList<CustomItem> itemList, selectedList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_menu);
txtOrder = (TextView) findViewById(R.id.txt1);
txtMember = (TextView) findViewById(R.id.txt2);
txtPrice = (TextView) findViewById(R.id.txt3);
list=(ListView) findViewById(R.id.listView);
btnAdd = (Button)findViewById(R.id.button);
rows = new ArrayList<String>();
itemList=new ArrayList<CustomItem>();
itemList.add(new CustomItem("Fried Rice","description","1","Quantity"));
itemList.add(new CustomItem("Fried Noodle","description","2","Quantity"));
itemList.add(new CustomItem("Prawn noodle","description","3","Quantity"));
itemList.add(new CustomItem("Chicken Rice","description","4","Quantity"));
int[] prgmImages={R.drawable.friedrice,R.drawable.friednoodle,R.drawable.pnoodle,R.drawable.chickenrice};
listView1 = (ListView) findViewById(R.id.listView);
final CustomLVAdapter customLVAdapter = new CustomLVAdapter(this, itemList,prgmImages);
listView1.setAdapter(customLVAdapter);
btnSubmit = (Button) findViewById(R.id.button);
btnSubmit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String strOrder = txtOrder.getText().toString();
String strMember = txtMember.getText().toString();
String strPrice = txtPrice.getText().toString();
StringBuffer responseText = new StringBuffer();
selectedList = new ArrayList<CustomItem>();
int total = 0;
for (int i = 0; i < itemList.size(); i++) {
CustomItem object = itemList.get(i);
if (object.isSelected()) {
responseText.append(object.getItem() + "," + object.getQty() + ",");//item
selectedList.add(object);
//calculate price
total = total + Integer.parseInt(object.getQty()) * Integer.parseInt(object.getPrice());
}
}
Add(responseText.toString(), "5565", String.valueOf(total));
Intent i = new Intent(getApplicationContext(), ReceiptActivity.class);
i.putExtra("Order",strOrder);
i.putExtra("Member",strMember);
i.putExtra("Price",strPrice);
startActivity(i);
Toast.makeText(getApplicationContext(), responseText + " $" + total,
Toast.LENGTH_SHORT).show();
SelectAll();
//store in database
//go to ReceiptActivity - membership, item, totalprice
}
});
}
public void Add(final String item, final String membership, final String price)
{
RequestQueue MyRequestQueue = Volley.newRequestQueue(this);
String url = server + "/insertorder.php";
StringRequest MyStringRequest = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}) {
protected Map<String, String> getParams() {
Map<String, String> MyData = new HashMap<String, String>();
MyData.put("item",item );
MyData.put("membership",membership );
MyData.put("price",price );
return MyData;
}
};
MyRequestQueue.add(MyStringRequest);
SelectAll();
}
public void SelectAll()
{
RequestQueue MyRequestQueue = Volley.newRequestQueue(this);
String url = server + "/fetchorder.php";
StringRequest MyStringRequest = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject jsonResponse = new JSONObject(response);
JSONArray jsonMainNode = jsonResponse.optJSONArray(sql_table);
rows.clear();
for(int i=0; i < jsonMainNode.length(); i++)
{
JSONObject jsonChildNode = jsonMainNode.getJSONObject(i);
String order = jsonChildNode.optString("item").toString();
String membership = jsonChildNode.optString("membership").toString();
String price = jsonChildNode.optString("price").toString();
rows.add(order + ", " + membership + ", " + price );
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(MenuActivity.this,
android.R.layout.simple_list_item_1, rows);
list.setAdapter(adapter);
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() { //Create an error listener to handle errors appropriately.
#Override
public void onErrorResponse(VolleyError error) {
//This code is executed if there is an error.
}
});
MyRequestQueue.add(MyStringRequest);
}
}
recieptactivity (the results should be displayed here)
public class ReceiptActivity extends Activity {
static public String txtOrder = "";
TextView foodorder;
ArrayList<CustomItem> itemList, selectedList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_receipt);
Bundle extras = getIntent().getExtras();
String strOrder = extras.getString("Order");
String strMember = extras.getString("Member");
String strPrice = extras.getString("Price");
TextView foodorder = (TextView)findViewById(R.id.foodorder);
foodorder.setText("hey"+strOrder);
menu.xml :
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".MenuActivity">
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/listView"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Submit Order"
android:id="#+id/button"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true" />
listview.xml :
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView1"
android:id="#+id/txt1"
android:textStyle="bold"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
style="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView2"
android:id="#+id/txt2"
android:textStyle="bold"
android:layout_below="#+id/txt1"
android:layout_alignStart="#+id/txt1" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView3"
android:id="#+id/txt3"
android:textStyle="bold"
android:layout_below="#+id/txt2"
android:layout_alignStart="#+id/txt2" />
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/ckBox"
android:checked="false"
android:layout_below="#+id/txt3"
android:layout_alignStart="#+id/txt3"
/>
<ImageView
android:id="#+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:scaleType="fitXY"
android:gravity="left"
android:layout_alignBottom="#+id/ckBox"
android:layout_toStartOf="#+id/txt1"
android:layout_alignParentEnd="false"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true" />
<NumberPicker
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/numberPicker"
android:layout_toEndOf="#+id/txt2"
android:layout_marginStart="23dp"
android:layout_alignParentTop="true"
android:layout_alignBottom="#+id/ckBox" />
customadapter :
public class CustomLVAdapter extends BaseAdapter {
private Context context;
LayoutInflater inflater;
private ArrayList<CustomItem> objectList;
private int[] imageId;
public static ArrayList<CustomItem> arl_food=new ArrayList<>();
private class ViewHolder {
TextView txt1,txt2,txt3;
CheckBox ckBox;
ImageView image;
NumberPicker np;
}
public CustomLVAdapter(Context context, ArrayList<CustomItem> objectList,int[]prgmImages){
this.context = context;
this.inflater = LayoutInflater.from(context);
this.objectList = objectList;
this.imageId = prgmImages;
this.objectList=objectList;
arl_food.clear();
for(int i=0;i<this.objectList.size();i++)
{
arl_food.add(this.objectList.get(i));
}
}
public int getCount(){
return objectList.size();
}
public CustomItem getItem (int position) {
return objectList.get(position);
}
public long getItemId(int position) {
return position;
}
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.row_checkbox_textview, null);
holder.txt1 = (TextView) convertView.findViewById(R.id.txt1);
holder.txt2 = (TextView) convertView.findViewById(R.id.txt2);
holder.txt3 = (TextView) convertView.findViewById(R.id.txt3);
holder.image=(ImageView) convertView.findViewById(R.id.image);
holder.ckBox = (CheckBox) convertView.findViewById(R.id.ckBox);
holder.np = (NumberPicker) convertView.findViewById(R.id.numberPicker);
holder.np.setMinValue(0);
holder.np.setMaxValue(10);
convertView.setTag(holder);
holder.ckBox.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
CheckBox cb = (CheckBox) v;
CustomItem object = (CustomItem) cb.getTag();
Toast.makeText(context,
"You have selected: " + object.getItem() +
"Price: " + object.getPrice() +
"Qty: " + object.getQty(),
Toast.LENGTH_LONG).show();
object.setSelected(cb.isChecked());
arl_food.get(position).setSelected(cb.isChecked());
}
}
);
holder.np.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
#Override
public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
NumberPicker p = picker;
CustomItem object = (CustomItem) p.getTag();
object.setQty(String.valueOf(newVal));
arl_food.get(position).setQty(String.valueOf(newVal));
}
});
}
else {
holder = (ViewHolder) convertView.getTag();
}
CustomItem object = objectList.get(position);
holder.txt1.setText(object.getItem());
holder.txt2.setText(object.getDesc());
holder.txt3.setText(object.getPrice());
holder.np.setTag(object);
holder.image.setImageResource(imageId[position]);
holder.ckBox.setChecked(object.isSelected());
holder.ckBox.setTag(object);
return convertView;
}
}
customitem :
public class CustomItem {
private int id;
private String item;
private String price;
private String desc;
private String qty;
private Boolean selected = false;
public CustomItem(){
}
public CustomItem(String item,String desc, String price,String qty){
this.item=item;
this.desc=desc ;
this.price=price;
this.qty=qty;
}
public CustomItem(int id, String item,String desc, String price,String qty){
this.id=id;
this.item=item;
this.desc=desc;
this.price=price;
this.qty=qty;
}
public int getId(){
return id;
}
public void setId (int id) {
this.id=id;
}
public String getItem(){
return item;
}
public void setItem(String item){
this.item=item;
}
public String getDesc()
{
return desc;
}
public void setDesc(String desc) {
this.desc=desc;
}
public String getPrice()
{
return price;
}
public void setPrice(String price) {
this.price=price;
}
public String getQty()
{
return qty;
}
public void setQty(String qty) {
this.qty=qty;
}
public boolean isSelected(){
return selected;
}
public void setSelected(boolean selected){
this.selected=selected;
}
logcat :
06-30 15:25:59.969 7196-7196/com.example.android.cardemulation E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.android.cardemulation, PID: 7196
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.CharSequence android.widget.TextView.getText()' on a null object reference
at com.example.android.cardemulation.MenuActivity$1.onClick(MenuActivity.java:79)
at android.view.View.performClick(View.java:5226)
at android.view.View$PerformClick.run(View.java:21266)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:168)
at android.app.ActivityThread.main(ActivityThread.java:5845)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:797)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:687)
You can not use this in to your Activity.
txtOrder = (TextView) findViewById(R.id.txt1);
txtMember = (TextView) findViewById(R.id.txt2);
txtPrice = (TextView) findViewById(R.id.txt3);
You should use another approach to get selected item data.
You can get from itemList or selectedList and can process further.