More logically, if synchronization occurs via a port / socket, on the one hand it simplifies the task (no need to cycle HTTP requests to check new messages, it is enough to check the status of the listening socket), but on the other hand, it complicates the creation of the server part of the application.
CREATE TABLE `chat` ( `_id` int(11) NOT NULL AUTO_INCREMENT, `author` text CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL, `client` text CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL, `data` bigint(20) NOT NULL, `text` text CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL, PRIMARY KEY (`_id`) )
$mysql_host = "localhost"; // sql , . mysql5.000webhost.com $mysql_user = "l29340eb_chat"; // $mysql_password = "123456789"; // $mysql_database = "l29340eb_chat"; // SQL
<?php // utf-8 ! // ---------------------------------------------------------- $mysql_host = "localhost"; // sql $mysql_user = "l29340eb_chat"; // $mysql_password = "123456789"; // $mysql_database = "l29340eb_chat"; // chat // ---------------------------------------------------------- // ...chat.php?action=select //----------------------------------------------------------- // action : // select - chat JSON // insert - chat, 4 : // / // , // delete - chat - // ------------------------------------------- action if (isset($_GET["action"])) { $action = $_GET['action']; } // ------------------------------------------- action=insert author|client|text if (isset($_GET["author"])) { $author = $_GET['author']; } if (isset($_GET["client"])) { $client = $_GET['client']; } if (isset($_GET["text"])) { $text = $_GET['text']; } // ------------------------------------------- action=select data - if (isset($_GET["data"])) { $data = $_GET['data']; } mysql_connect($mysql_host, $mysql_user, $mysql_password); // SQL mysql_select_db($mysql_database); // mysql_set_charset('utf8'); // // ------------------------------------------------------------ if($action == select){ // SELECT if($data == null){ // chat JSON $q=mysql_query("SELECT * FROM chat"); }else{ // chat JSON $q=mysql_query("SELECT * FROM chat WHERE data > $data"); } while($e=mysql_fetch_assoc($q)) $output[]=$e; print(json_encode($output)); } if($action == insert && $author != null && $client != null && $text != null){ // INSERT // = ! $current_time = round(microtime(1) * 1000); // : // chat.php?action=insert&author=author&client=client&text=text // mysql_query("INSERT INTO `chat`(`author`,`client`,`data`,`text`) VALUES ('$author','$client','$current_time','$text')"); } if($action == delete){ // DELETE // mysql_query("TRUNCATE TABLE `chat`"); } mysql_close(); ?>
<?php // utf-8 ! // -------------------------------------------------------------------------- $mysql_host = "localhost"; // sql $mysql_user = "l29340eb_chat"; // $mysql_password = "123456789"; // $mysql_database = "l29340eb_chat"; // chat // -------------------------------------------------------------------------- if (!mysql_connect($mysql_host, $mysql_user, $mysql_password)){ echo "<h2> !</h2>"; exit; }else{ // -------------------------------------------------------------------------- echo "<h2> !</h2>"; mysql_select_db($mysql_database); mysql_set_charset('utf8'); // -------------------------------------------------------------------------- JSON $q=mysql_query("SELECT * FROM chat"); echo "<h3>Json :</h3>"; // json while($e=mysql_fetch_assoc($q)) $output[]=$e; print(json_encode($output)); // -------------------------------------------------------------------------- $q=mysql_query("SELECT * FROM chat"); echo "<h3> :</h3>"; echo "<table border=\"1\" width=\"100%\" bgcolor=\"#999999\">"; echo "<tr><td>_id</td><td>author</td>"; echo "<td>client</td><td>data</td><td>text</td></tr>"; for ($c=0; $c<mysql_num_rows($q); $c++){ $f = mysql_fetch_array($q); echo "<tr><td>$f[_id]</td><td>$f[author]</td><td>$f[client]</td><td>$f[data]</td><td>$f[text]</td></tr>"; } echo "</tr></table>"; } mysql_close(); // -------------------------------------------------------------------------- ?>
package by.andreidanilevich.temp_chat; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import org.json.JSONArray; import org.json.JSONObject; import android.app.Notification; import android.app.PendingIntent; import android.app.Service; import android.content.ContentValues; import android.content.Context; import android.content.Intent; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.graphics.BitmapFactory; import android.os.IBinder; import android.util.Log; public class FoneService extends Service { // (url ) // http://l29340eb.bget.ru String server_name = "http://l29340eb.bget.ru"; SQLiteDatabase chatDBlocal; HttpURLConnection conn; Cursor cursor; Thread thr; ContentValues new_mess; Long last_time; // , // , @Override public IBinder onBind(Intent intent) { return null; } public void onStart(Intent intent, int startId) { Log.i("chat", "+ FoneService - "); chatDBlocal = openOrCreateDatabase("chatDBlocal.db", Context.MODE_PRIVATE, null); chatDBlocal .execSQL("CREATE TABLE IF NOT EXISTS chat (_id integer primary key autoincrement, author, client, data, text)"); // notification // "" // Intent iN = new Intent(getApplicationContext(), MainActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); PendingIntent pI = PendingIntent.getActivity(getApplicationContext(), 0, iN, PendingIntent.FLAG_CANCEL_CURRENT); Notification.Builder bI = new Notification.Builder( getApplicationContext()); bI.setContentIntent(pI) .setSmallIcon(R.drawable.ic_launcher) .setLargeIcon( BitmapFactory.decodeResource(getApplicationContext() .getResources(), R.drawable.ic_launcher)) .setAutoCancel(true) .setContentTitle(getResources().getString(R.string.app_name)) .setContentText("..."); Notification notification = bI.build(); startForeground(101, notification); startLoop(); } // , // // . // - // ListView ChatActivity private void startLoop() { thr = new Thread(new Runnable() { // ansver = // lnk = String ansver, lnk; public void run() { while (true) { // // cursor = chatDBlocal.rawQuery( "SELECT * FROM chat ORDER BY data", null); // - - // if (cursor.moveToLast()) { last_time = cursor.getLong(cursor .getColumnIndex("data")); lnk = server_name + "/chat.php?action=select&data=" + last_time.toString(); // - // } else { lnk = server_name + "/chat.php?action=select"; } cursor.close(); // ----------------------------------> try { Log.i("chat", "+ FoneService --------------- "); conn = (HttpURLConnection) new URL(lnk) .openConnection(); conn.setReadTimeout(10000); conn.setConnectTimeout(15000); conn.setRequestMethod("POST"); conn.setRequestProperty("User-Agent", "Mozilla/5.0"); conn.setDoInput(true); conn.connect(); } catch (Exception e) { Log.i("chat", "+ FoneService : " + e.getMessage()); } // ----------------------------------> try { InputStream is = conn.getInputStream(); BufferedReader br = new BufferedReader( new InputStreamReader(is, "UTF-8")); StringBuilder sb = new StringBuilder(); String bfr_st = null; while ((bfr_st = br.readLine()) != null) { sb.append(bfr_st); } Log.i("chat", "+ FoneService - :\n" + sb.toString()); // string // , "]" // , .. json // - ansver = sb.toString(); ansver = ansver.substring(0, ansver.indexOf("]") + 1); is.close(); // br.close(); // } catch (Exception e) { Log.i("chat", "+ FoneService : " + e.getMessage()); } finally { conn.disconnect(); Log.i("chat", "+ FoneService --------------- "); } // ----------------------------------> if (ansver != null && !ansver.trim().equals("")) { Log.i("chat", "+ FoneService ---------- JSON:"); try { // JSON JSONArray ja = new JSONArray(ansver); JSONObject jo; Integer i = 0; while (i < ja.length()) { // JSON jo = ja.getJSONObject(i); Log.i("chat", "=================>>> " + jo.getString("author") + " | " + jo.getString("client") + " | " + jo.getLong("data") + " | " + jo.getString("text")); // new_mess = new ContentValues(); new_mess.put("author", jo.getString("author")); new_mess.put("client", jo.getString("client")); new_mess.put("data", jo.getLong("data")); new_mess.put("text", jo.getString("text")); // chatDBlocal.insert("chat", null, new_mess); new_mess.clear(); i++; // ChatActivity // - ListView sendBroadcast(new Intent( "by.andreidanilevich.action.UPDATE_ListView")); } } catch (Exception e) { // JSON Log.i("chat", "+ FoneService ---------- :\n" + e.getMessage()); } } else { // Log.i("chat", "+ FoneService ---------- JSON!"); } try { Thread.sleep(15000); } catch (Exception e) { Log.i("chat", "+ FoneService - : " + e.getMessage()); } } } }); thr.setDaemon(true); thr.start(); } }
package by.andreidanilevich.temp_chat; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLEncoder; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import android.annotation.SuppressLint; import android.app.Activity; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.os.AsyncTask; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.ListView; import android.widget.SimpleAdapter; import android.widget.Toast; public class ChatActivity extends Activity { // (url ) // http://l29340eb.bget.ru String server_name = "http://l29340eb.bget.ru"; ListView lv; // EditText et; Button bt; SQLiteDatabase chatDBlocal; String author, client; INSERTtoChat insert_to_chat; // UpdateReceiver upd_res; // - // ListView @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.chat); // 2 : // author - // client - Intent intent = getIntent(); author = intent.getStringExtra("author"); client = intent.getStringExtra("client"); Log.i("chat", "+ ChatActivity - author = " + author + " | client = " + client); lv = (ListView) findViewById(R.id.lv); et = (EditText) findViewById(R.id.et); bt = (Button) findViewById(R.id.bt); chatDBlocal = openOrCreateDatabase("chatDBlocal.db", Context.MODE_PRIVATE, null); chatDBlocal .execSQL("CREATE TABLE IF NOT EXISTS chat (_id integer primary key autoincrement, author, client, data, text)"); // upd_res = new UpdateReceiver(); registerReceiver(upd_res, new IntentFilter( "by.andreidanilevich.action.UPDATE_ListView")); create_lv(); } // lv = lv @SuppressLint("SimpleDateFormat") public void create_lv() { Cursor cursor = chatDBlocal.rawQuery( "SELECT * FROM chat WHERE author = '" + author + "' OR author = '" + client + "' ORDER BY data", null); if (cursor.moveToFirst()) { // // // , hashmap // cursor ArrayList<HashMap<String, Object>> mList = new ArrayList<HashMap<String, Object>>(); HashMap<String, Object> hm; do { // !!! // = // = if (cursor.getString(cursor.getColumnIndex("author")).equals( author) && cursor.getString(cursor.getColumnIndex("client")) .equals(client)) { hm = new HashMap<>(); hm.put("author", author); hm.put("client", ""); hm.put("list_client", ""); hm.put("list_client_time", ""); hm.put("list_author", cursor.getString(cursor.getColumnIndex("text"))); hm.put("list_author_time", new SimpleDateFormat( "HH:mm - dd.MM.yyyy").format(new Date(cursor .getLong(cursor.getColumnIndex("data"))))); mList.add(hm); } // !!!!!!! // = // = if (cursor.getString(cursor.getColumnIndex("author")).equals( client) && cursor.getString(cursor.getColumnIndex("client")) .equals(author)) { hm = new HashMap<>(); hm.put("author", ""); hm.put("client", client); hm.put("list_author", ""); hm.put("list_author_time", ""); hm.put("list_client", cursor.getString(cursor.getColumnIndex("text"))); hm.put("list_client_time", new SimpleDateFormat( "HH:mm - dd.MM.yyyy").format(new Date(cursor .getLong(cursor.getColumnIndex("data"))))); mList.add(hm); } } while (cursor.moveToNext()); // lv SimpleAdapter adapter = new SimpleAdapter(getApplicationContext(), mList, R.layout.list, new String[] { "list_author", "list_author_time", "list_client", "list_client_time", "author", "client" }, new int[] { R.id.list_author, R.id.list_author_time, R.id.list_client, R.id.list_client_time, R.id.author, R.id.client }); lv.setAdapter(adapter); cursor.close(); } Log.i("chat", "+ ChatActivity ======================== "); } public void send(View v) { // // if (!et.getText().toString().trim().equals("")) { // bt.setEnabled(false); // - ! insert_to_chat = new INSERTtoChat(); insert_to_chat.execute(); } else { // - et.setText(""); } } // private class INSERTtoChat extends AsyncTask<Void, Void, Integer> { HttpURLConnection conn; Integer res; protected Integer doInBackground(Void... params) { try { // String post_url = server_name + "/chat.php?action=insert&author=" + URLEncoder.encode(author, "UTF-8") + "&client=" + URLEncoder.encode(client, "UTF-8") + "&text=" + URLEncoder.encode(et.getText().toString().trim(), "UTF-8"); Log.i("chat", "+ ChatActivity - : " + et.getText().toString().trim()); URL url = new URL(post_url); conn = (HttpURLConnection) url.openConnection(); conn.setConnectTimeout(10000); // 10 conn.setRequestMethod("POST"); conn.setRequestProperty("User-Agent", "Mozilla/5.0"); conn.connect(); res = conn.getResponseCode(); Log.i("chat", "+ ChatActivity - (200 - ): " + res.toString()); } catch (Exception e) { Log.i("chat", "+ ChatActivity - : " + e.getMessage()); } finally { // conn.disconnect(); } return res; } protected void onPostExecute(Integer result) { try { if (result == 200) { Log.i("chat", "+ ChatActivity - ."); // et.setText(""); } } catch (Exception e) { Log.i("chat", "+ ChatActivity - :\n" + e.getMessage()); Toast.makeText(getApplicationContext(), " ", Toast.LENGTH_SHORT).show(); } finally { // bt.setEnabled(true); } } } // FoneService // , - ListView public class UpdateReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Log.i("chat", "+ ChatActivity - - ListView"); create_lv(); } } // public void onBackPressed() { Log.i("chat", "+ ChatActivity - "); unregisterReceiver(upd_res); finish(); } }
package by.andreidanilevich.temp_chat; import java.net.HttpURLConnection; import java.net.URL; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.database.sqlite.SQLiteDatabase; import android.os.AsyncTask; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.Spinner; import android.widget.Toast; public class MainActivity extends Activity { // (url ) // http://l29340eb.bget.ru String server_name = "http://l29340eb.bget.ru"; Spinner spinner_author, spinner_client; String author, client; Button open_chat_btn, open_chat_reverce_btn, delete_server_chat; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Log.i("chat", "+ MainActivity - "); open_chat_btn = (Button) findViewById(R.id.open_chat_btn); open_chat_reverce_btn = (Button) findViewById(R.id.open_chat_reverce_btn); delete_server_chat = (Button) findViewById(R.id.delete_server_chat); // FoneService this.startService(new Intent(this, FoneService.class)); // 2 // 5 5 // spinner_author = (Spinner) findViewById(R.id.spinner_author); spinner_client = (Spinner) findViewById(R.id.spinner_client); spinner_author.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, new String[] { "", "", "", "", "", "", "", "", "", "" })); spinner_client.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, new String[] { "", "", "", "", "", "", "", "", "", "" })); spinner_client.setSelection(5); open_chat_btn.setText(" : " + spinner_author.getSelectedItem().toString() + " > " + spinner_client.getSelectedItem().toString()); open_chat_reverce_btn.setText(" : " + spinner_client.getSelectedItem().toString() + " > " + spinner_author.getSelectedItem().toString()); spinner_author .setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { public void onItemSelected(AdapterView<?> parent, View itemSelected, int selectedItemPosition, long selectedId) { author = spinner_author.getSelectedItem().toString(); open_chat_btn.setText(" : " + spinner_author.getSelectedItem().toString() + " > " + spinner_client.getSelectedItem().toString()); open_chat_reverce_btn.setText(" : " + spinner_client.getSelectedItem().toString() + " > " + spinner_author.getSelectedItem().toString()); } public void onNothingSelected(AdapterView<?> parent) { } }); spinner_client .setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { public void onItemSelected(AdapterView<?> parent, View itemSelected, int selectedItemPosition, long selectedId) { client = spinner_client.getSelectedItem().toString(); open_chat_btn.setText(" : " + spinner_author.getSelectedItem().toString() + " > " + spinner_client.getSelectedItem().toString()); open_chat_reverce_btn.setText(" : " + spinner_client.getSelectedItem().toString() + " > " + spinner_author.getSelectedItem().toString()); } public void onNothingSelected(AdapterView<?> parent) { } }); } // public void open_chat(View v) { // if (author.equals(client)) { // // Toast.makeText(this, "author = client !", Toast.LENGTH_SHORT) .show(); } else { // author > client Intent intent = new Intent(MainActivity.this, ChatActivity.class); intent.putExtra("author", author); intent.putExtra("client", client); startActivity(intent); } } // , public void open_chat_reverce(View v) { // if (author.equals(client)) { // // Toast.makeText(this, "author = client !", Toast.LENGTH_SHORT) .show(); } else { // client > author Intent intent = new Intent(MainActivity.this, ChatActivity.class); intent.putExtra("author", client); intent.putExtra("client", author); startActivity(intent); } } // public void delete_server_chats(View v) { Log.i("chat", "+ MainActivity - "); delete_server_chat.setEnabled(false); delete_server_chat.setText(" . ..."); DELETEfromChat delete_from_chat = new DELETEfromChat(); delete_from_chat.execute(); } // // public void delete_local_chats(View v) { Log.i("chat", "+ MainActivity - "); SQLiteDatabase chatDBlocal; chatDBlocal = openOrCreateDatabase("chatDBlocal.db", Context.MODE_PRIVATE, null); chatDBlocal.execSQL("drop table chat"); chatDBlocal .execSQL("CREATE TABLE IF NOT EXISTS chat (_id integer primary key autoincrement, author, client, data, text)"); Toast.makeText(getApplicationContext(), " !", Toast.LENGTH_SHORT).show(); } // // - // ( ) // - private class DELETEfromChat extends AsyncTask<Void, Void, Integer> { Integer res; HttpURLConnection conn; protected Integer doInBackground(Void... params) { try { URL url = new URL(server_name + "/chat.php?action=delete"); conn = (HttpURLConnection) url.openConnection(); conn.setConnectTimeout(10000); // 10 conn.setRequestMethod("POST"); conn.setRequestProperty("User-Agent", "Mozilla/5.0"); conn.connect(); res = conn.getResponseCode(); Log.i("chat", "+ MainActivity - (200 = ): " + res.toString()); } catch (Exception e) { Log.i("chat", "+ MainActivity - : " + e.getMessage()); } finally { conn.disconnect(); } return res; } protected void onPostExecute(Integer result) { try { if (result == 200) { Toast.makeText(getApplicationContext(), " !", Toast.LENGTH_SHORT) .show(); } } catch (Exception e) { Toast.makeText(getApplicationContext(), " .", Toast.LENGTH_SHORT) .show(); } finally { // delete_server_chat.setEnabled(true); delete_server_chat.setText(" !"); } } } public void onBackPressed() { Log.i("chat", "+ MainActivity - "); finish(); } }
package by.andreidanilevich.temp_chat; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.util.Log; public class AutoRun extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) { // boot_completed - FoneService context.startService(new Intent(context, FoneService.class)); Log.i("chat", "+ AutoRun - "); } } } <b>:</b>
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="by.andreidanilevich.temp_chat" android:versionCode="1" android:versionName="1.0" > <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <uses-sdk android:minSdkVersion="16" android:targetSdkVersion="22" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:label="@string/app_name" android:screenOrientation="portrait" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".ChatActivity" android:label="@string/app_name" android:screenOrientation="portrait" > </activity> <receiver android:name=".AutoRun" android:enabled="true" android:exported="false" > <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> </intent-filter> </receiver> <service android:name=".FoneService" /> </application> </manifest>
<?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="#999999" > <ListView android:id="@+id/lv" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginBottom="60dp" android:scrollbars="none" android:stackFromBottom="true" android:transcriptMode="alwaysScroll" > </ListView> <LinearLayout android:layout_width="match_parent" android:layout_height="60dp" android:layout_alignParentBottom="true" android:background="#ffffff" > <EditText android:id="@+id/et" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_gravity="top" android:layout_weight="1" android:ems="10" > </EditText> <Button android:id="@+id/bt" android:layout_width="50dp" android:layout_height="wrap_content" android:layout_gravity="top" android:onClick="send" android:text=">" /> </LinearLayout> </RelativeLayout>
<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="${relativePackage}.${activityClass}" > <Spinner android:id="@+id/spinner_author" android:layout_width="match_parent" android:layout_height="wrap_content" /> <Spinner android:id="@+id/spinner_client" android:layout_width="match_parent" android:layout_height="wrap_content" /> <Button android:id="@+id/open_chat_btn" android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="open_chat" /> <Button android:id="@+id/open_chat_reverce_btn" android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="open_chat_reverce" /> <Button android:id="@+id/delete_server_chat" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="50dp" android:onClick="delete_server_chats" android:text=" !" /> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="delete_local_chats" android:text=" !" /> </LinearLayout>
<?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:background="#999999" android:orientation="vertical" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="5dp" > <TextView android:id="@+id/author" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="left" android:textColor="#c6c6c6" android:textSize="12sp" /> <TextView android:id="@+id/client" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="left" android:textColor="#c6c6c6" android:textSize="12sp" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="5dp" android:layout_marginTop="5dp" > <TextView android:id="@+id/list_author" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="left" android:textColor="#0000ff" android:textSize="14sp" android:textStyle="bold" /> <TextView android:id="@+id/list_client" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="left" android:textColor="#ffff00" android:textSize="14sp" android:textStyle="bold" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="5dp" > <TextView android:id="@+id/list_author_time" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="right" android:textColor="#c6c6c6" android:textSize="12sp" /> <TextView android:id="@+id/list_client_time" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="right" android:textColor="#c6c6c6" android:textSize="12sp" /> </LinearLayout> </LinearLayout>
Source: https://habr.com/ru/post/269135/
All Articles