We will see here how to create dynamic layout in android and parsing of JSON data inside the dynamic layout. We will also see how to show image inside the dynamic layout. Movie and Channel category app like Hotstar, Youtube , Netflix uses the same logic to show there data but design and functionality are different.
I have created one simple activity and loaded JSON data from server. We will also learn how to use and create LinearLayout, TextView, ImageView dynamically.
Hotstar.java:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 |
package in.nfluence.nfluencemovies; import android.app.ProgressDialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Color; import android.net.ConnectivityManager; import android.net.Uri; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.os.StrictMode; import android.util.Log; import android.view.Gravity; import android.view.View; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.view.Menu; import android.view.MenuItem; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; import org.apache.http.NameValuePair; import org.apache.http.client.HttpClient; import org.apache.http.client.ResponseHandler; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.BasicResponseHandler; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.message.BasicNameValuePair; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import android.widget.HorizontalScrollView; import android.widget.LinearLayout; import android.widget.GridLayout; import android.widget.RelativeLayout; /** * Created by ${ajinkya} on ${2016-04-04}. */ public class Hotstar extends AppCompatActivity{ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (android.os.Build.VERSION.SDK_INT > 9) { StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy(policy); } setContentView(R.layout.movies_main); new LoadMovieData(Hotstar.this).execute("http://192.168.1.8/nFluenceMovies/database/Movies.php"); } private class LoadMovieData extends AsyncTask<String, Void, String> { ProgressDialog pDialog; public Hotstar activity; public LoadMovieData(Hotstar a) { this.activity = a; } @Override protected void onPreExecute() { super.onPreExecute(); ImageView seticon=(ImageView)findViewById(R.id.setIcon); seticon.setImageResource(R.drawable.hotstar); TextView heading=(TextView)findViewById(R.id.movietv); heading.setTextColor(Color.parseColor("#5ccf09")); heading.setText("Hotstar"); pDialog = new ProgressDialog((Hotstar.this)); pDialog.setProgressStyle(android.R.style.Widget_ProgressBar_Large); pDialog.setCancelable(false); pDialog.show(); } @Override protected String doInBackground(String... params) { //Data will be sent to the server as a list of KeyValue pairs. String url=params[0]; Log.d("MainActivity", "before try:"); try { Log.d("MainActivity", "in try:"); HttpClient httpclient=new DefaultHttpClient(); HttpPost httppost=new HttpPost(url); List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(0); nameValuePairs.add(new BasicNameValuePair("category","Hotstar")); httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs)); ResponseHandler<String> responseHandler = new BasicResponseHandler(); String response = httpclient.execute(httppost, responseHandler); Log.d("MainActivity", "Toast:" + response); return response; } catch (Exception e) { e.printStackTrace(); } return null; } // onPostExecute displays the results of the AsyncTask. @Override protected void onPostExecute(String result) { super.onPostExecute(result); pDialog.dismiss(); try { JSONObject json = new JSONObject(result); JSONArray categories; categories = json.getJSONArray("hotstar"); GridLayout layout = (GridLayout)findViewById(R.id.gridmovie); //Movies for (int i = 0; i < categories.length(); i++) { final JSONObject catObj = (JSONObject) categories.get(i); LinearLayout linearLayout = new LinearLayout(Hotstar.this); LinearLayout.LayoutParams lp_ineer_ver = new LinearLayout.LayoutParams( 300, LinearLayout.LayoutParams.WRAP_CONTENT); /*if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { linearLayout.setBackground(getResources().getDrawable(R.drawable.border)); }*/ linearLayout.setGravity(Gravity.CENTER); linearLayout.setOrientation(LinearLayout.VERTICAL); linearLayout.setLayoutParams(lp_ineer_ver); layout.addView(linearLayout); ImageView imageButton = new ImageView(Hotstar.this); LinearLayout.LayoutParams lpImage = new LinearLayout.LayoutParams(250,250); lpImage.gravity=Gravity.CENTER; //Setting the parameters on the Image imageButton.setLayoutParams(lpImage); if(!(catObj.get("link").toString().isEmpty())){ Bitmap bitmap = loadImage(catObj.get("link").toString()); imageButton.setImageBitmap(bitmap); imageButton.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { Intent intent = new Intent(); intent.setAction(Intent.ACTION_VIEW); intent.addCategory(Intent.CATEGORY_BROWSABLE); try { intent.setData(Uri.parse(catObj.get("redirectlink").toString())); } catch (JSONException e) { e.printStackTrace(); } startActivity(intent); } }); } //adding imageview to relative layout linearLayout.addView(imageButton); TextView textview = new TextView(Hotstar.this); LinearLayout.LayoutParams lpTextView = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); //Setting the parameters on the TextView textview.setLayoutParams(lpTextView); // textview.setBackgroundResource(android.R.color.holo_red_light); textview.setText(catObj.get("name").toString()); // textview.setTextSize(50); //textview.setPadding(60,0,0,0); textview.bringToFront(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { textview.setTextAlignment(View.TEXT_ALIGNMENT_CENTER); } //Adding TextView to relative layout linearLayout.addView(textview); // layout.addView(name); Log.d("MAINLINKS:", catObj.get("link").toString()); } }catch (Exception e) { e.printStackTrace(); } } } protected Bitmap loadImage(String utl2) { // TODO Auto-generated method stub Log.v("utl2--", utl2); URL imageURL = null; Bitmap bitmap = null; try { imageURL = new URL(utl2); } catch (MalformedURLException e) { e.printStackTrace(); } try { HttpURLConnection connection = (HttpURLConnection) imageURL .openConnection(); connection.setDoInput(true); connection.connect(); InputStream inputStream = connection.getInputStream(); bitmap = BitmapFactory.decodeStream(inputStream); } catch (IOException e) { e.printStackTrace(); } return bitmap; } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); //noinspection SimplifiableIfStatement if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } } |
Here AsyncTask class is an abstract class which helps us to use the UI thread. It is mostly used when we are doing any network related operation. This class overrides the methods doInBackground, onPostExecute, onPreExecuteon, ProgressUpdate. See the official doc Here.
In method doInBackground HTTP POST method used to connect and fetch JSON data from server. See the post if you want to know how to connect android to MySQL/PHP . When doInBackground method complete it’s processing then it’s result passed to onPostExecute method.
You can create dynamically layout like this:
1 2 3 4 5 6 7 |
TextView textview = new TextView(Hotstar.this); LinearLayout.LayoutParams lpTextView = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); //Setting the parameters on the TextView textview.setLayoutParams(lpTextView); |
You can add your design methods like setText() already mentioned in code. In this way you can create layouts and add ImageView, TexView etc.
Here JSONObject and JSONArray class is used to parse JSON data.
The following parameters received as a JSON parsing :
- ‘hotstar’– Â Main Array which differentiate category for example if you are creating other category of this Activity class then it will be categorised.
- ‘link’– Â This parameter contains the string URL. It is very hard process to send image in JSON and it will slow down your server if you sending the direct image in JSON format. So , It is good practice to send only URL and when app receives this URL it loads the image in ImageView. Here Bitmap class used to show image from URL in ImageView. (See in above code line no. 149)
- ‘redirectlink’– Here in code ImageView will act like a HTML image link. Intent Action used to do this function. When user click on ImageView then it will ask user to open link in Browser or Hotstar.
- ‘name’– Description of clickable image shown by TextView exactly below of ImageView.
These all parameters added to form single layout dynamically in for loop.
You can show your existing GridView layout from XML file to java file :
1 |
GridLayout layout = (GridLayout)findViewById(R.id.gridmovie); |
Each single data including above above JSON strings with images added in GridLayout. Here ScrollView used to show dynamic data. See below movies_main.xml.
movies_main.xml:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
<?xml version="1.0" encoding="utf-8"?> <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/scrollView" android:layout_width="match_parent" android:layout_height="wrap_content"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <RelativeLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal"> <ImageView android:layout_width="40dp" android:layout_height="40dp" android:src="@drawable/movies" android:layout_weight="1" android:id="@+id/setIcon" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textStyle="bold" android:id="@+id/movietv" android:textSize="30dp" android:textColor="#591471" android:paddingLeft="42dp" android:layout_weight="1" /> </RelativeLayout> <View android:layout_width="match_parent" android:layout_height="10dp" android:background="@android:color/white"/> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> <GridLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:layout_gravity="center" android:columnCount="3" android:rowCount="3" android:id="@+id/gridmovie" > </GridLayout> </RelativeLayout> </LinearLayout> </ScrollView> |
Movies.php:
When server receive POST request from app then it send data in JSON format. Here using PHP I have send JSON data to app client using HTTP POST method. The POST parameter ‘category’ receive on server side. Then using PHP PDO method it fetches all data from MySQL database and encodes this data in JSON format. You can see detail explanation about PHP PDO(PHP Data Objects) here with android connection.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
<?php $category=$_POST['category']; function hotstar(){ include "connectandroid.php"; try { // begin the transaction $conn->beginTransaction(); $statement = $conn->prepare("SELECT * FROM tblmovies where category=:category order by cdate desc"); $statement->execute(array(':category' => "H")); if ($statement->rowCount() > 0){ $check = $statement->fetchAll(PDO::FETCH_ASSOC); //$check will now hold an array of returned rows. //let's say we need the second result, i.e. index of 1 // $row_id = $check[1]['id']; // do something $response["hotstar"]=array(); for($i=0;$i<$statement->rowCount();$i++){ $hotstar['link'] = $check[$i]['link']; $hotstar['name'] = $check[$i]['name']; $hotstar['redirectlink'] = $check[$i]['redirectlink']; array_push($response["hotstar"],$hotstar); } } return @$response; // commit the transaction $conn->commit(); } catch(PDOException $e) { // roll back the transaction if something failed $conn->rollback(); echo "Error: " . $e->getMessage(); } $conn = null; } if($category=="Hotstar"){ $a=hotstar(); header('Content-type: application/json'); //echo(json_encode($response)); echo str_replace('\/','/',json_encode($a)); } else{ echo "NO Data found"; } ?> |
connectandroid.php:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<?php $servername = "localhost"; $username = "root"; $password = ""; $database="nf_movies"; try { $conn = new PDO("mysql:host=$servername;dbname=$database", $username, $password); // set the PDO error mode to exception $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } catch(PDOException $e) { echo "Connection failed: " . $e->getMessage(); } ?> |
Result on app:
- Simple GridLayout of data :
2. When User Click any ImageView then it will show like this:
If You have any query regarding this post feel free to comment !
Hi,
Thanks for the info, But How do I get to know the data which I have is also available on Hotstar?
And how did you get the data to link it to Hotstar.?
is there any json API from Hotstar?
Hi bishwajith bn,
This post is about to ‘BUILD’ app like HOTSTAR. It is not related to get direct data from hotstar. I have explained only how to build movies category app like Hotstar, Sonyliv- LIVE, OZEE etc just to clear concept of dynamic layout and JSON parsing. If you want​ to show data from Hotstar app then you have to contact developers of Hotstar. Some apps do the same process. For example , OZEE app gets data from Ditto TV app. If you want to build something big or do business from your app then only contact to Hotstar.
Thanks,
Ajinkya