Displaying picture, name and description in a listView android - java

Im trying to display some information from my Items[] in a listview, the information is retrived from database. what I want to display is a picture, name and description. note that the picture is retrived in base64 string so I have to convert it before sending data.
I tried this:
for(int x=0;x<items.length;x++) {
byte[] decodedString = Base64.decode(items[x].Picture, Base64.DEFAULT);
Bitmap decodedByte = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
ListAdapter adapter = new SimpleAdapter(Itemlist.this, (List<? extends Map<String, ?>>) listView, R.layout.layout, new String[]{items[x].Name, items[x].Description}, new int[]{R.id.move_title, R.id.move_rating});
setListAdapter(adapter);
}
but I got this error:
java.lang.ClassCastException: android.widget.ListView cannot be cast to java.util.List
this is the activity layout:
<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" tools:context=".MainActivity"
android:background="#ffffff"
>
<ListView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</ListView>
</RelativeLayout>
and the list layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent"
android:background="#ffffff"
>
<ImageView
android:id="#+id/move_poster"
android:layout_width="100dp"
android:layout_height="75dp"
android:layout_alignParentLeft="true"
/>
<View
android:layout_width="match_parent"
android:layout_height="2dp"
android:background="#FFFFFF"
android:layout_alignRight="#+id/move_poster"
android:layout_alignEnd="#+id/move_poster"
android:layout_below="#+id/move_poster">
</View>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Large Text"
android:id="#+id/move_title"
android:layout_alignParentTop="true"
android:layout_toRightOf="#+id/move_poster"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Text"
android:id="#+id/move_rating"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_below="#+id/move_title"
android:layout_toRightOf="#+id/move_poster"
android:layout_toEndOf="#+id/move_poster"
android:layout_alignBottom="#+id/move_poster" />
</RelativeLayout>
and this is the whole activity class:
public class Itemlist extends ListActivity {
private Handler mHandler= new Handler();
Item[] items;
ListView listView;
MoveAdapter adapter;
TextView tv;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_itemlist);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
listView=getListView();
tv=(TextView)findViewById(R.id.textView);
String[] params= new String[]{"192.168.1.11:90"};
new MyAsyncTask().execute(params);
}
class MyAsyncTask extends AsyncTask<String, Void, String>
{
public String SOAP_ACTION="http://tempuri.org/GetAllItems";
public String OPERATION_NAME ="GetAllItems";
public String WSDL_TARGET_NAMESPACE ="http://tempuri.org/";
public String SOAP_ADDRESS;
private SoapObject request;
private HttpTransportSE httpTransport;
private SoapSerializationEnvelope envelop;
Object response= null;
#Override
protected String doInBackground(String... params) {
SOAP_ADDRESS = "http://" + params[0] + "/myWebService2.asmx";
request = new SoapObject(WSDL_TARGET_NAMESPACE, OPERATION_NAME);
envelop = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelop.dotNet = true;
envelop.setOutputSoapObject(request);
httpTransport = new HttpTransportSE(SOAP_ADDRESS);
try {
httpTransport.call(SOAP_ACTION, envelop);
SoapObject response = (SoapObject) envelop.getResponse();
items = new Item[response.getPropertyCount()];
for (int i = 0; i < items.length; i++) {
SoapObject pii = (SoapObject) response.getProperty(i);
Item item = new Item();
item.Name = pii.getProperty(0).toString();
item.Description = pii.getProperty(1).toString();
item.Picture = pii.getProperty(2).toString();
item.ID = Integer.parseInt(pii.getProperty(3).toString());
items[i] = item;
}
} catch (XmlPullParserException e) {
e.printStackTrace();
} catch (SoapFault soapFault) {
soapFault.printStackTrace();
} catch (HttpResponseException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return "Done"; }
#Override
protected void onPostExecute(final String result){
super.onPostExecute(result);
mHandler.post(new Runnable() {
#Override
public void run() {
tv.setText(result);
for(int x=0;x<items.length;x++) {
byte[] decodedString = Base64.decode(items[x].Picture, Base64.DEFAULT);
Bitmap decodedByte = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
ListAdapter adapter = new SimpleAdapter(Itemlist.this, (List<? extends Map<String, ?>>) listView, R.layout.layout, new String[]{items[x].Name, items[x].Description}, new int[]{R.id.move_title, R.id.move_rating});
setListAdapter(adapter);
}
}
});
}
}
}
also I don't know how to send the bitmap format of the picture to the adapter, because it only takes Strings.
can someone please help me displaying the listview of images, name and description?

Actually i think i have some time to do it now,
here we go.
but first you need to read and learn Custom adapter for listView
you can google it and understand how it works,
then come back to this answer.
here you can findsome good sample for a custom adapter
you really need to read and understand it.
now, some code changes for your's
1- modify your Item class to have a Bitmap Member
public Bitmap bitmap;
adding setter and getter is better. but you can make it public and access it directly
2- [Optional] in Itemlist activity, declare Arraylist instead of array
you will learn more about this when you search for custom adapter, as you can pass data as Array or as List
private ArrayList<Item> items = new ArrayList();
3- modify the for loop as following: (assuming you did not changed to arrayList and still use array[])
for(int x=0;x<items.length;x++) {
byte[] decodedString = Base64.decode(items[x].Picture, Base64.DEFAULT);
Bitmap decodedByte = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
items[x].bitmap = decodedByte;
}//for loop end
4- declare adapter (instance of your Custom Adapter), and assign it to the listView
MyCustomAdapter adapter = new MyCustomAdapter(ItemsList.this, R.layout.list_row, items);
setListAdapter(adapter);
now in your adapter's getView() method, you can use the memebrs (name, desc, bitmap) to populate the custom layout of each row
that's it.
P.S: this code is not all compiled, and may contain some typos,
it's just to guide you through the process.

Related

Issue with multiple Volley requests

Whenever I want to perform Volley request based on user input I must press button twice to instead of click the button only one time to get the requested response.
I Used wait() function, but still have the same problem and application corrupted, while I expected the application work normally.
This is what I have reached to until now:
String URL="https://apifootball.com/api/?action=get_countries&APIkey=b4c74bf2fcf3937f783b752649018a42a3b1bde9d5d7c03ff36f61fc06c00c77";
RequestQueue rq= Volley.newRequestQueue(this);
JsonArrayRequest objreq= new JsonArrayRequest(
Request.Method.GET,
URL,
null,
new Response.Listener<JSONArray>()
{
#Override
public void onResponse(JSONArray response) {
try {
Log.e("result:",response.get(0).toString());
JSONObject obj;
for (int count = 0; count < response.length(); count++) {
obj = response.getJSONObject(count);
String name = obj.getString("country_name");
Log.e("Country:",name);
send(name,true);
// Team t=new Team(2,"mki");
//x.insertTeam(t);
//so on
}
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener(){
#Override
public void onErrorResponse(VolleyError error) {
Log.e("rest response",error.toString());
}
}
);
rq.add(objreq);
btn_send_message.setOnClickListener(new View.OnClickListener() {
ChatModel model;
public void onClick(View v) {
String text = editText.getText().toString();
else if(text.contains("result"))
{
ChatModel model = new ChatModel(text, true); // user send message
list_chat.add(model);
String result="";
String head2Head;
String input[] = text.split(" ");
String[] arr=null ;
DBAdapter dbAdapter=new DBAdapter(x);
try{
result=dbAdapter.getResultfromDB("Bristol City","Reading");
}catch (Exception e)
{
result="error";
}
if(result.equals("error")==true) {
APIAdapter ap = new APIAdapter();
head2Head = ap.getResult("Bristol City", "Reading", "kjkn", getApplicationContext());
finres = head2Head;
Log.e("headto",head2Head);
arr = head2Head.split("\n");
}
model = new ChatModel("First team:"+arr[0]+"\nSecond team:"+arr[1]+"\n"+"Date:"+arr[2], false);
list_chat.add(model);
}
}
Now I do understand your question. The thing that is happening is the data is taking its time to be loaded. So use something like a progress bar and change its visibility inside Response.Listener and Response.ErrorListener. To make this work properly move the line rq.add(objreq); inside onClickListener and before this line change the visibility of the progress bar to visible.
Example
Layout.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/mainParentRel"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="#drawable/grad_bg_2"
android:isScrollContainer="true"
android:scrollbars="vertical">
<ScrollView
android:id="#+id/scrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:fillViewport="true"
android:scrollbars="vertical">
<!-- You can use any thing here
Put all your previous buttons edittext etc here.
You can replace the scrollview with any layout
Or You can completely remove the scrollview and
directly put your views here. -->
</ScrollView>
<!-- This is the progress bar layout. Always remember to set its visibility to GONE.-->
<RelativeLayout
android:id="#+id/progressRelLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:visibility="gone">
<ImageView
android:id="#+id/company_logo_progress"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_centerHorizontal="true"
android:adjustViewBounds="true"
android:contentDescription="#string/company_logo"
android:scaleType="fitCenter"
android:src="#drawable/company_logo" />
<ProgressBar
android:id="#+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/company_logo_progress"
android:layout_marginTop="5dp"
android:layout_centerHorizontal="true"
android:theme="#style/WhiteAccent"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/progressBar"
android:text="Loading..."
android:textColor="#color/white"
android:textSize="17dp"
android:layout_centerHorizontal="true"/>
</RelativeLayout>
</RelativeLayout>
Example.java
RelativeLayout progressRL;
//Inside onCreate()
progressRL= findViewById(R.id.progressRelLayout);
//Do rest of your stuff
String URL="https://apifootball.com/api/?action=get_countries&APIkey=b4c74bf2fcf3937f783b752649018a42a3b1bde9d5d7c03ff36f61fc06c00c77";
RequestQueue rq= Volley.newRequestQueue(this);
JsonArrayRequest objreq= new JsonArrayRequest(
Request.Method.GET,
URL,
null,
new Response.Listener<JSONArray>()
{
#Override
public void onResponse(JSONArray response) {
progressRL.setVisibility(View.GONE);
try {
Log.e("result:",response.get(0).toString());
JSONObject obj;
for (int count = 0; count < response.length(); count++) {
obj = response.getJSONObject(count);
String name = obj.getString("country_name");
Log.e("Country:",name);
send(name,true);
// Team t=new Team(2,"mki");
//x.insertTeam(t);
//so on
}
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener(){
#Override
public void onErrorResponse(VolleyError error) {
progressRL.setVisibility(View.GONE);
Log.e("rest response",error.toString());
}
}
);
btn_send_message.setOnClickListener(new View.OnClickListener() {
ChatModel model;
public void onClick(View v) {
rq.add(objreq);
progressRL.setVisibility(View.VISIBLE);
String text = editText.getText().toString();
else if(text.contains("result"))
{
ChatModel model = new ChatModel(text, true); // user send message
list_chat.add(model);
String result="";
String head2Head;
String input[] = text.split(" ");
String[] arr=null ;
DBAdapter dbAdapter=new DBAdapter(x);
try{
result=dbAdapter.getResultfromDB("Bristol City","Reading");
}catch (Exception e)
{
result="error";
}
if(result.equals("error")==true) {
APIAdapter ap = new APIAdapter();
head2Head = ap.getResult("Bristol City", "Reading", "kjkn", getApplicationContext());
finres = head2Head;
Log.e("headto",head2Head);
arr = head2Head.split("\n");
}
model = new ChatModel("First team:"+arr[0]+"\nSecond team:"+arr[1]+"\n"+"Date:"+arr[2], false);
list_chat.add(model);
}
}
After doing this it might cause errors. Just move the things that will change after loading of data inside Response.Listener.

How to go from one fragment to another, from an other java class?

I have a login page on fragment connected to BackgroundWorker class which has database connectivity.
my login page sends texts from EditTexts to BackgroundWorker Class, then all the database queries(by accessing PHP files from WAMP) are done in the BackgroundWorker class.
When i click the login button on my fragment it opens the dialog box which tells me if login was successful or not. (the code of dialog box exists in BackgroundWorker class (Please refer the code if i am not being clear) )
but the thing is, i don't want dialog box, i want to go from one fragment to another from that BackgroundWorker.java file.
i have the code of how can i go from one activity to another, but not of fragment
fragment XML FILE
<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"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context="com.example.admin.blingiton.Client_login">
<!-- TODO: Update blank fragment layout -->
<RelativeLayout
android:id="#+id/ClientLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/back"
android:layout_width="wrap_content"
android:layout_height="600dp"
android:layout_alignParentBottom="true"
android:layout_alignParentStart="true"
android:scaleType="fitXY"
app:srcCompat="#drawable/back" />
<ImageView
android:id="#+id/mirae"
android:layout_width="300dp"
android:layout_height="250dp"
android:layout_alignParentBottom="true"
android:layout_alignParentStart="true"
android:layout_marginBottom="12dp"
android:layout_marginStart="32dp"
android:scaleType="centerInside"
app:srcCompat="#drawable/mirae" />
<ImageView
android:id="#+id/header"
android:layout_width="wrap_content"
android:layout_height="600dp"
android:layout_alignBottom="#+id/mirae"
android:layout_alignParentStart="true"
android:layout_marginBottom="20dp"
android:scaleType="fitStart"
app:srcCompat="#drawable/header" />
<EditText
android:id="#+id/cusername"
android:layout_width="200dp"
android:layout_height="35dp"
android:layout_alignTop="#+id/mirae"
android:layout_centerHorizontal="true"
android:layout_marginTop="13dp"
android:background="#drawable/username"
android:ems="10"
android:hint="username"
android:inputType="textPersonName"
android:textAlignment="center" />
<EditText
android:id="#+id/cpassword"
android:layout_width="200dp"
android:layout_height="35dp"
android:layout_alignStart="#+id/cusername"
android:layout_below="#+id/cusername"
android:layout_marginTop="18dp"
android:background="#drawable/password"
android:ems="10"
android:hint="password"
android:inputType="textPassword"
android:textAlignment="center" />
<Button
android:id="#+id/clogin"
android:layout_width="200dp"
android:layout_height="35dp"
android:layout_above="#+id/signupbtn"
android:layout_alignStart="#+id/cpassword"
android:layout_marginBottom="11dp"
android:background="#drawable/login" />
<Button
android:id="#+id/signupbtn"
android:layout_width="200dp"
android:layout_height="35dp"
android:layout_alignBottom="#+id/mirae"
android:layout_alignStart="#+id/clogin"
android:background="#drawable/signup"
/>
<ImageView
android:id="#+id/imageView"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:src="#drawable/log" />
</RelativeLayout>
<RelativeLayout
android:id="#+id/afterlogin"
android:layout_width="match_parent"
android:layout_height="match_parent">
</RelativeLayout>
</RelativeLayout>
Fragment.java file
EditText UsernameEt, PasswordEt;
Button login;
View v;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
v = inflater.inflate(R.layout.fragment_clientlogin, container, false);
UsernameEt = (EditText) v.findViewById(R.id.cusername);
PasswordEt = (EditText) v.findViewById(R.id.cpassword);
login = (Button) v.findViewById(R.id.clogin);
login.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String username = UsernameEt.getText().toString();
String password = PasswordEt.getText().toString();
String type = "login";
BackgroundWorker backgroundWorker = new
BackgroundWorker(getActivity());
backgroundWorker.execute(type, username, password);
}
});
return v;
}
BackgroundWorker.java < /b>
Context context;
AlertDialog alertDialog;
BackgroundWorker(Context ctx) {
context = ctx;
}
#Override
protected String doInBackground(String...params) {
String type = params[0];
String login_url = "http://192.168.10.2/login.php";
if (type.equals("login")) {
try {
String user_name = params[1];
String password = params[2];
URL url = new URL(login_url);
HttpURLConnection httpURLConnection =
(HttpURLConnection) url.openConnection();
httpURLConnection.setRequestMethod("POST");
httpURLConnection.setDoOutput(true);
httpURLConnection.setDoInput(true);
OutputStream outputStream = httpURLConnection.getOutputStream();
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8"));
String post_data = URLEncoder.encode("user_name", "UTF-
8 ")+" = "+URLEncoder.encode(user_name,"
UTF - 8 ")+" & " +
URLEncoder.encode("password", "UTF-
8 ")+" = "+URLEncoder.encode(password,"
UTF - 8 ");
bufferedWriter.write(post_data);
bufferedWriter.flush();
bufferedWriter.close();
outputStream.close();
InputStream inputStream = httpURLConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new
InputStreamReader(inputStream, "iso-8859-1"));
String result = ""; String line = "";
while ((line = bufferedReader.readLine()) != null) {
result += line;
}
bufferedReader.close(); inputStream.close(); httpURLConnection.disconnect();
return result;
}
catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
#Override
protected void onPreExecute() {
alertDialog = new AlertDialog.Builder(context).create();
alertDialog.setTitle("Login Status");
}
#Override
protected void onPostExecute(String result) {
Client_login cl = new Client_login();
alertDialog.setMessage(result);
//alertDialog.show();
if (result.contentEquals("login success !!!!! Welcome user")) {
//Code Here.
} else {
Toast toast = Toast.makeText(context, "Email or password is wrong",
Toast.LENGTH_SHORT);
toast.show();
}
}
#Override
protected void onProgressUpdate(Void...values) {
super.onProgressUpdate(values);
}
try to use this if you find any error please let me know.
First create a interface
interface ChangeFragment
{
public void chfragment();
}
Then your second fragment
public class SecondFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// this is your success login fragment
return inflater.inflate(R.layout.fragment_second, container, false);
}
}
After that your activity where you place the login fragment
public class Successfull extends Activity implements ChangeFragment
{
protected void onCreate(android.os.Bundle savedInstanceState) {
//your code
}
}
#Override
public void chfragment()
{
SecondFragment yoursecondfragment=new SecondFragment();
FragmentManager manager=getSupportedFragmentManager();
FragmentTransaction transaction=manager.beginTransaction();
transaction.replace(R.layout.framelayout,yoursecondfragment);
transaction.commit();
}
}
then your backgroundworker thread
Context context;
AlertDialog alertDialog;
BackgroundWorker (Context ctx) {
context = ctx;
}
#Override
protected String doInBackground(String... params) {
String type = params[0];
String login_url = "http://192.168.10.2/login.php";
if(type.equals("login")) {
try {
String user_name = params[1];
String password = params[2];
URL url = new URL(login_url);
HttpURLConnection httpURLConnection =
(HttpURLConnection)url.openConnection();
httpURLConnection.setRequestMethod("POST");
httpURLConnection.setDoOutput(true);
httpURLConnection.setDoInput(true);
OutputStream outputStream = httpURLConnection.getOutputStream();
BufferedWriter bufferedWriter = new BufferedWriter(new
OutputStreamWriter(outputStream, "UTF-8"));
String post_data = URLEncoder.encode("user_name","UTF-
8")+"="+URLEncoder.encode(user_name,"UTF-8")+"&"
+URLEncoder.encode("password","UTF-
8")+"="+URLEncoder.encode(password,"UTF-8");
bufferedWriter.write(post_data);
bufferedWriter.flush();
bufferedWriter.close();
outputStream.close();
InputStream inputStream = httpURLConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new
InputStreamReader(inputStream,"iso-8859-1"));
String result="";
String line="";
while((line = bufferedReader.readLine())!= null) {
result += line;
}
bufferedReader.close();
inputStream.close();
httpURLConnection.disconnect();
return result;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
#Override
protected void onPreExecute() {
alertDialog = new AlertDialog.Builder(context).create();
alertDialog.setTitle("Login Status");
}
#Override
protected void onPostExecute(String result) {
Client_login cl = new Client_login();
alertDialog.setMessage(result);
//alertDialog.show();
if(result.contentEquals("login success !!!!! Welcome user")) {
//Code Here.
ChangeFragment frag=new Successfull();
frag.chfragment();
}else
{
Toast toast= Toast.makeText(context, "Email or password is wrong",
Toast.LENGTH_SHORT);
toast.show();
}
}
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
I think this code will help you.

How to populate a RecyclerView with data from a Service on Button click

I have this setup in my fragment. The user makes selections from the spinners and when they click the go button a service is initiated that is meant to get data and populate a recycler view with the data.The recycler view is located right below the spinners.The code is below.
<?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">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp">
<Spinner
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/weekSpinner"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_margin="5dp">
</Spinner>
<Spinner
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/sessionSpinner"
android:layout_toRightOf="#+id/weekSpinner"
android:layout_toEndOf="#+id/weekSpinner"
android:layout_margin="5dp">
</Spinner>
<Spinner
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/termSpinner"
android:layout_toRightOf="#+id/sessionSpinner"
android:layout_toEndOf="#+id/sessionSpinner"
android:layout_margin="5dp">
</Spinner>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Go"
android:id="#+id/resultsSearch"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_margin="10dp"
android:layout_below="#+id/sessionSpinner"
android:textColor="#android:color/white"
android:background="#color/toolBar"/>
</RelativeLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/caRecycler">
</android.support.v7.widget.RecyclerView>
</LinearLayout>
</LinearLayout>
I am getting this error.
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object android.content.Context.getSystemService(java.lang.String)' on a null object reference
I understand that it has to do with the context being used but i have no idea how to solve it as this is the first time i'm using this sort of setup. Below is my fragment code.
public class caFragment extends Fragment
{
ArrayList<String> weeks,terms,sessions;
String selectedWeek,selectedTerm,selectedSession;
String activeChild;
Button go;
private static final String selectedChildTracker = "selectedChild";
SharedPreferences sharedpreferences;
static RecyclerView caDisplay = null;
static caCardAdapter cardAdapter = null;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.results_ca,null);
sharedpreferences = this.getActivity().getSharedPreferences(selectedChildTracker, Context.MODE_PRIVATE);
activeChild = sharedpreferences.getString("selectedChild",null);
final Spinner week,term,session;
setup();
week = (Spinner) view.findViewById(R.id.weekSpinner);
ArrayAdapter<String> weekAdapter = new ArrayAdapter<>(getContext(),android.R.layout.simple_spinner_item,weeks);
weekAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
week.setAdapter(weekAdapter);
term = (Spinner) view.findViewById(R.id.termSpinner);
ArrayAdapter<String> termAdapter = new ArrayAdapter<>(getContext(),android.R.layout.simple_spinner_item,terms);
termAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
term.setAdapter(termAdapter);
session = (Spinner) view.findViewById(R.id.sessionSpinner);
ArrayAdapter<String> sessionAdapter = new ArrayAdapter<>(getContext(),android.R.layout.simple_spinner_item,sessions);
sessionAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
session.setAdapter(sessionAdapter);
caDisplay = (RecyclerView) view.findViewById(R.id.caRecycler);
go = (Button) view.findViewById(R.id.resultsSearch);
go.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View view)
{
selectedWeek = week.getSelectedItem().toString();
selectedTerm = term.getSelectedItem().toString();
selectedSession = session.getSelectedItem().toString();
Bundle extra = new Bundle();
extra.putString("selectedWeek",selectedWeek);
extra.putString("selectedTerm",selectedTerm);
extra.putString("selectedSession",selectedSession);
extra.putString("selectedChild",activeChild);
try
{
getActivity().startService(new Intent(getContext(), results.class).putExtras(extra));
}
catch (Exception ex)
{
System.out.print(ex);
}
}
});
return view;
}
public void setup()
{
weeks = new ArrayList<>();
terms = new ArrayList<>();
sessions = new ArrayList<>();
try
{
weeks.add("4");
weeks.add("8");
}
catch (Exception ex)
{
Log.e("Error adding weeks",ex.toString());
}
try
{
terms.add("First Term");
terms.add("Second Term");
terms.add("Third Term");
}
catch (Exception ex)
{
Log.e("Error adding terms",ex.toString());
}
try
{
sessions.add("2015/2016");
}
catch (Exception ex)
{
Log.e("Error adding sessions",ex.toString());
}
}
public void showResults()
{
cardAdapter = new caCardAdapter(getActivity(),cardResults.getResultSet());
caDisplay.setAdapter(cardAdapter);
caDisplay.setLayoutManager(new LinearLayoutManager(getActivity()));
}
}
and below is my service code
public class results extends Service
{
int mStartMode;
String tag_results_req = "tag_results_req";
static ArrayList<cardResults> cardResult;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
Bundle params = intent.getExtras();
Log.d("bundle param",params.toString());
String week = params.getString("selectedWeek");
String term = params.getString("selectedTerm");
String session = params.getString("selectedSession");
String child = params.getString("selectedChild");
makeRequest(week,term,session,child);
return mStartMode;
}
#Override
public void onDestroy()
{
super.onDestroy();
}
public void makeRequest(String week,String term,String session,String child)
{
String dataSet = week.trim()+","+term+","+session.trim()+","+child.trim();
byte[] data = new byte[0];
try
{
data = dataSet.getBytes("UTF-8");
}
catch (UnsupportedEncodingException e)
{
e.printStackTrace();
}
String query = Base64.encodeToString(data, Base64.DEFAULT);
Log.d("Query param",query);
//the url we are posting the request to
String url = " http://mobile.map.education/api/result/ca/"+query;
// prepare the Request
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url, null,
new Response.Listener<JSONObject>()
{
#Override
public void onResponse(JSONObject response)
{
// display response
Log.d("results",response.toString());
cardResults(response);
}
},
new Response.ErrorListener()
{
#Override
public void onErrorResponse(VolleyError error)
{
Log.e("Error.Response", error.toString());
Toast.makeText(getApplicationContext(),"Sorry there was an error getting results data",Toast.LENGTH_LONG).show();
}
}
);
queuer.getInstance().addToRequestQueue(request, tag_results_req);
}
public void cardResults(JSONObject result)
{
cardResult = new ArrayList<>();
JSONArray res = null;
try
{
res = (JSONArray) result.get("result_details");
Log.d("results",res.toString());
}
catch (Exception ex)
{
Log.e("error getting results",ex.toString());
}
for (int i = 0; i < res.length(); i++)
{
try
{
JSONObject subject = res.getJSONObject(i);
cardResults cardModel = new cardResults();
cardModel.setAverage("50");
cardModel.setScore(subject.getString("total"));
cardModel.setSubject(subject.getString("subject"));
cardModel.setAssignment(subject.getString("ASSIGNMENT"));
cardModel.setTest(subject.getString("CLASS TEST"));
cardModel.setWork(subject.getString("CLASS WORK"));
cardModel.setTeacher(subject.getString("teacher"));
cardResult.add(cardModel);
}
catch (Exception ex)
{
Log.e("card list",ex.toString());
}
}
try {
cardResults.setResultSet(cardResult);
caFragment m = new caFragment();
m.showResults();
}
catch (Exception ex)
{
Log.e("show result",ex.toString());
}
}
}
Looks like problem with your adapter which you are setting outside the onCreate of Fragment
cardAdapter = new caCardAdapter(getActivity());
caDisplay.setAdapter(cardAdapter);
caDisplay.setLayoutManager(new LinearLayoutManager(getActivity()));
move above lines inside the onCreate and just create one data Setter method in your Adapter class and then call this method to set data.
public void showResults()
{
//create setter method inside your adapter and notify
cardAdapter.setData(cardResults.getResultSet());
cardAdapter.notifyDataSetChanged();
}
before set Data just check that your data is not null!

Android Calling API and parsing JSON

Trying to make an API call to the url below and parse the returning JSON, when the "refresh" button is called.
I can link to a button and get text (Hello world) to the screen, but can't seem to link the button click to the API request. Error message says I cannot reference non-static method "execute" from a static context
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void retrieveInformation(View view){
RetrieveFeedTask.execute();
TextView textview = (TextView) findViewById(R.id.responseView);
textview.setText("Hello world");
}
class RetrieveFeedTask extends AsyncTask<Void, Void, String> {
String jsonString = "";
private Exception exception;
protected void onPreExecute() {
}
protected String doInBackground(Void... urls) {
// Do some validation here
try {
URL url = new URL("www.liftin.co.uk/api/v1/journeys");
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
try {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
StringBuilder stringBuilder = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
stringBuilder.append(line).append("\n");
}
bufferedReader.close();
return stringBuilder.toString();
} finally {
urlConnection.disconnect();
}
} catch (Exception e) {
Log.e("ERROR", e.getMessage(), e);
return null;
}
}
protected void onPostExecute(String response) {
if (response == null) {
response = "THERE WAS AN ERROR";
}
Log.i("INFO", response);
jsonString = response;
try {
getInformationFromJson(jsonString);
} catch (JSONException e) {
e.printStackTrace();
}
}
private String getInformationFromJson(String jsonString)
throws JSONException {
final String DRIVER = "driver";
final String START = "start";
final String DESTINATION = "destination";
final String TIME = "pick_up_time";
final String PASSENGERS = "passengers";
final String SEATS = "seats_available";
JSONObject journeyJson = new JSONObject(jsonString);
String time = journeyJson.getString(TIME);
String seats = journeyJson.getString(SEATS);
String results = seats + "-----" + time;
return results;
}
}
}
Main_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context="com.example.android.liftin.MainActivity">
<Button
android:id="#+id/queryButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="end"
style="#style/Base.Widget.AppCompat.Button.Borderless"
android:text="Refresh"
android:onClick="retrieveInformation"/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/responseView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</ScrollView>
</RelativeLayout>
</LinearLayout>
You should create asynchronous call for your AsyncTask like this :
public void retrieveInformation(View view){
new RetrieveFeedTask().execute(); //asynchronous call
TextView textview = (TextView) findViewById(R.id.responseView);
textview.setText("Hello world");
}
UPDATE
If you want to set data to textview after parsing data. You have to make little bit changes in your activity as follows.
You should initialize your textview in onCreate() and make it global variable for your activity, so that you can access it in full activity.
then in your onPostExecute() do this :
textview.setText(getInformationFromJson(response));
Hope it will Help :)
You must create a object of AsyncTask (RetrieveFeedTask) before calling it. For example
public void retrieveInformation(View view){
TextView textview = (TextView) findViewById(R.id.responseView);
textview.setText("Hello world");
new RetrieveFeedTask().execute();
}
You still need to pass something for Void.
public void retrieveInformation(View view){
new RetrieveFeedTask().execute(null);
TextView textview = (TextView) findViewById(R.id.responseView);
textview.setText("Hello world");
}

Can you please help me with this code?

The problem: When I Type a ID and press the button, it will not load the ID's webpage...
"a url" is the website page i'm trying to create, (Hidden for number of reasons)
It should be working, it loads the first site, but when I try to call for the IDs, the WebView does not change... Can someone please help me? -Thanks, JG1
My code:
#Override
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
wv.setWebViewClient(new OurViewClient());
wv.getSettings().setJavaScriptEnabled(true);
try {
String url = "a url";
wv.loadUrl(url);
} catch (Exception e) {
e.printStackTrace();
}
String lid = "0";
//Clicking button changes to the color
}
final EditText idbox = (EditText) findViewById(R.id.editText1);
final Button idbutton = (Button) findViewById(R.id.idbtn);
final WebView wv = (WebView) findViewById(R.id.webView1);
public void onClick(View v) {
idbutton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
String lid = idbox.getText().toString();
if (lid == "1") {
wv.setWebViewClient(new OurViewClient());
try {
String urla = "a url";
wv.loadUrl(urla);
} catch (Exception e) {
e.printStackTrace();
}
}
if (lid == "2") {
wv.setWebViewClient(new OurViewClient());
try {
String urlb = "a url";
wv.loadUrl(urlb);
} catch (Exception e) {
e.printStackTrace();
}
}
if (lid == "3") {
wv.setWebViewClient(new OurViewClient());
try {
String urlc = "a url";
wv.loadUrl(urlc);
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
}
I guess, You had been called the same URL value like ("a url"). If yes, try to load different URLs in the web view.
If not, do the following changes in your code,
Put break points to debug your code where you get EditText value.
String lid = idbox.getText().toString(); //check lid is null or not
Change the if condition like this,
if(lid.equalsIgnoreCase("1"))
{
//task for rendering web page
}
Check your custom view client class.
Never mind, You written onClick() method definition is wrongly!
I confused because,
Have you been adding the onclick(android:onClick="onClick") function for button in xml.
In spite of I did some bit changes in your code,
activity_main.xml:
<LinearLayout 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" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="2" >
<EditText
android:id="#+id/urlValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="2dp"
android:layout_weight="1.5" />
<Button
android:id="#+id/urlBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="2dp"
android:layout_weight="0.5"
android:text="load"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<WebView
android:id="#+id/webView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
MainActivity.java:
public class MainActivity extends Activity {
private EditText getUrlValue;
private Button loadUrl;
private WebView webView;
String loadId = "";
String URL_ONE = "a_url";
String URL_TWO = "b_url";
String URL_THREE = "c_url";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getUrlValue = (EditText)findViewById(R.id.urlValue);
loadUrl = (Button)findViewById(R.id.urlBtn);
webView = (WebView)findViewById(R.id.webView);
//initial view for webView
getUrlValue.setText("1"); //here web page will load first url= "a url"
webView.setWebViewClient(new OurViewClient());
//onClick Event for load url button
loadUrl.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
loadId = getUrlValue.getText().toString();
if(loadId.equalsIgnoreCase("1")){
try{
webView.loadUrl(URL_ONE);
}catch (Exception e){
e.printStackTrace();
}
}
else if(loadId.equalsIgnoreCase("2")){
try{
webView.loadUrl(URL_TWO);
}catch (Exception e){
e.printStackTrace();
}
}
else{
try{
webView.loadUrl(URL_THREE);
}catch (Exception e){
e.printStackTrace();
}
}
}
});
}
}
remember to add internet permission in the manifest xml file.

Categories