refactored ServerListAdapter and converted it to kotlin
This commit is contained in:
parent
4f12fd94ff
commit
2a1d2058e3
@ -16,12 +16,16 @@
|
||||
*/
|
||||
package net.schueller.peertube.activity
|
||||
|
||||
import android.app.Activity
|
||||
import android.app.AlertDialog
|
||||
import android.content.DialogInterface
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.widget.Toast
|
||||
import androidx.activity.viewModels
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import androidx.preference.PreferenceManager
|
||||
import androidx.recyclerview.widget.ItemTouchHelper
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import net.schueller.peertube.R
|
||||
@ -30,6 +34,9 @@ import net.schueller.peertube.database.Server
|
||||
import net.schueller.peertube.database.ServerViewModel
|
||||
import net.schueller.peertube.databinding.ActivityServerAddressBookBinding
|
||||
import net.schueller.peertube.fragment.AddServerFragment
|
||||
import net.schueller.peertube.helper.APIUrlHelper
|
||||
import net.schueller.peertube.network.Session
|
||||
import net.schueller.peertube.service.LoginService
|
||||
import java.util.*
|
||||
|
||||
class ServerAddressBookActivity : CommonActivity() {
|
||||
@ -77,8 +84,32 @@ class ServerAddressBookActivity : CommonActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun onServerClick(server: Server) {
|
||||
|
||||
val sharedPref = PreferenceManager.getDefaultSharedPreferences(this)
|
||||
val editor = sharedPref.edit()
|
||||
val serverUrl = APIUrlHelper.cleanServerUrl(server.serverHost)
|
||||
editor.putString(getString(R.string.pref_api_base_key), serverUrl)
|
||||
editor.apply()
|
||||
|
||||
// Logout if logged in
|
||||
val session = Session.getInstance()
|
||||
if (session.isLoggedIn) {
|
||||
session.invalidate()
|
||||
}
|
||||
|
||||
// attempt authentication if we have a username
|
||||
if (server.username.isNullOrBlank().not()) {
|
||||
LoginService.Authenticate(server.username, server.password)
|
||||
}
|
||||
|
||||
// close this activity
|
||||
finish()
|
||||
Toast.makeText(this, getString(R.string.server_selection_set_server, serverUrl), Toast.LENGTH_LONG).show()
|
||||
}
|
||||
|
||||
private fun showServers() {
|
||||
val adapter = ServerListAdapter(this).also {
|
||||
val adapter = ServerListAdapter(mutableListOf()) { onServerClick(it) }.also {
|
||||
mBinding.serverListRecyclerview.adapter = it
|
||||
}
|
||||
|
||||
@ -110,7 +141,7 @@ class ServerAddressBookActivity : CommonActivity() {
|
||||
|
||||
|
||||
// Update the cached copy of the words in the adapter.
|
||||
mServerViewModel.allServers.observe(this, { servers: List<Server?>? ->
|
||||
mServerViewModel.allServers.observe(this, { servers: List<Server> ->
|
||||
adapter.setServers(servers)
|
||||
|
||||
addServerFragment?.let {
|
||||
|
@ -1,156 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Stefan Schüller <sschueller@techdroid.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package net.schueller.peertube.adapter;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.text.TextUtils;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import net.schueller.peertube.R;
|
||||
|
||||
import net.schueller.peertube.database.Server;
|
||||
import net.schueller.peertube.helper.APIUrlHelper;
|
||||
import net.schueller.peertube.network.Session;
|
||||
import net.schueller.peertube.service.LoginService;
|
||||
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static android.app.Activity.RESULT_OK;
|
||||
|
||||
public class ServerListAdapter extends RecyclerView.Adapter<ServerListAdapter.ServerViewHolder> {
|
||||
|
||||
|
||||
private final LayoutInflater mInflater;
|
||||
private List<Server> mServers; // Cached copy of Servers
|
||||
|
||||
public ServerListAdapter(Context context) {
|
||||
this.mInflater = LayoutInflater.from(context);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ServerViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View itemView = mInflater.inflate(R.layout.row_server_address_book, parent, false);
|
||||
return new ServerViewHolder(itemView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull ServerViewHolder holder, int position) {
|
||||
|
||||
if (mServers != null) {
|
||||
Server current = mServers.get(position);
|
||||
holder.serverLabel.setText(current.getServerName());
|
||||
holder.serverUrl.setText(current.getServerHost());
|
||||
|
||||
if (TextUtils.isEmpty(current.getUsername())) {
|
||||
holder.hasLogin.setVisibility(View.GONE);
|
||||
} else {
|
||||
holder.hasLogin.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
} else {
|
||||
// Covers the case of data not being ready yet.
|
||||
holder.serverLabel.setText(R.string.server_book_no_servers_found);
|
||||
}
|
||||
|
||||
holder.itemView.setOnClickListener(v -> {
|
||||
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(mInflater.getContext());
|
||||
SharedPreferences.Editor editor = sharedPref.edit();
|
||||
|
||||
String serverUrl = APIUrlHelper.cleanServerUrl(getServerAtPosition(position).getServerHost());
|
||||
|
||||
editor.putString(mInflater.getContext().getString(R.string.pref_api_base_key), serverUrl);
|
||||
editor.apply();
|
||||
|
||||
// Logout if logged in
|
||||
Session session = Session.getInstance();
|
||||
if (session.isLoggedIn()) {
|
||||
session.invalidate();
|
||||
}
|
||||
|
||||
// attempt authentication if we have a username
|
||||
if (!TextUtils.isEmpty(getServerAtPosition(position).getUsername())) {
|
||||
LoginService.Authenticate(
|
||||
getServerAtPosition(position).getUsername(),
|
||||
getServerAtPosition(position).getPassword()
|
||||
);
|
||||
}
|
||||
|
||||
// tell server list activity to reload list
|
||||
Intent intent = new Intent();
|
||||
((Activity) mInflater.getContext()).setResult(RESULT_OK, intent);
|
||||
|
||||
// close this activity
|
||||
((Activity) mInflater.getContext()).finish();
|
||||
|
||||
Toast.makeText(mInflater.getContext(), mInflater.getContext().getString(R.string.server_selection_set_server, serverUrl), Toast.LENGTH_LONG).show();
|
||||
|
||||
});
|
||||
|
||||
|
||||
//
|
||||
// holder.itemView.setOnLongClickListener(v -> {
|
||||
// Log.v("ServerListAdapter", "setOnLongClickListener " + position);
|
||||
// return true;
|
||||
// });
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void setServers(List<Server> Servers) {
|
||||
mServers = Servers;
|
||||
this.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
// getItemCount() is called many times, and when it is first called,
|
||||
// mServers has not been updated (means initially, it's null, and we can't return null).
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
if (mServers != null)
|
||||
return mServers.size();
|
||||
else return 0;
|
||||
}
|
||||
|
||||
static class ServerViewHolder extends RecyclerView.ViewHolder {
|
||||
TextView serverLabel, serverUrl, serverUsername;
|
||||
ImageView hasLogin;
|
||||
|
||||
private ServerViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
serverLabel = itemView.findViewById(R.id.serverLabelRow);
|
||||
serverUrl = itemView.findViewById(R.id.serverUrlRow);
|
||||
hasLogin = itemView.findViewById(R.id.sb_row_has_login_icon);
|
||||
}
|
||||
}
|
||||
|
||||
public Server getServerAtPosition (int position) {
|
||||
return mServers.get(position);
|
||||
}
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Stefan Schüller <sschueller@techdroid.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package net.schueller.peertube.adapter
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import net.schueller.peertube.adapter.ServerListAdapter.ServerViewHolder
|
||||
import net.schueller.peertube.database.Server
|
||||
import net.schueller.peertube.databinding.RowServerAddressBookBinding
|
||||
import net.schueller.peertube.utils.visibleIf
|
||||
|
||||
class ServerListAdapter(private val mServers: MutableList<Server>, private val onClick: (Server) -> Unit) : RecyclerView.Adapter<ServerViewHolder>() {
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ServerViewHolder {
|
||||
|
||||
val binding = RowServerAddressBookBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
||||
|
||||
return ServerViewHolder(binding)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ServerViewHolder, position: Int) {
|
||||
|
||||
holder.bind(mServers[position])
|
||||
|
||||
//
|
||||
// holder.itemView.setOnLongClickListener(v -> {
|
||||
// Log.v("ServerListAdapter", "setOnLongClickListener " + position);
|
||||
// return true;
|
||||
// });
|
||||
}
|
||||
|
||||
fun setServers(servers: List<Server>) {
|
||||
mServers.clear()
|
||||
mServers.addAll(servers)
|
||||
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
// getItemCount() is called many times, and when it is first called,
|
||||
// mServers has not been updated (means initially, it's null, and we can't return null).
|
||||
override fun getItemCount(): Int {
|
||||
return mServers.size
|
||||
}
|
||||
|
||||
inner class ServerViewHolder (private val binding: RowServerAddressBookBinding) : RecyclerView.ViewHolder(binding.root) {
|
||||
|
||||
fun bind(server: Server) {
|
||||
|
||||
binding.serverLabelRow.text = server.serverName
|
||||
binding.serverUrlRow.text = server.serverHost
|
||||
binding.sbRowHasLoginIcon.visibleIf { server.username.isNullOrBlank().not() }
|
||||
|
||||
binding.root.setOnClickListener { onClick(server) }
|
||||
}
|
||||
}
|
||||
|
||||
fun getServerAtPosition(position: Int): Server {
|
||||
return mServers[position]
|
||||
}
|
||||
}
|
@ -1,86 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Stefan Schüller <sschueller@techdroid.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package net.schueller.peertube.database;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.room.ColumnInfo;
|
||||
import androidx.room.Entity;
|
||||
import androidx.room.PrimaryKey;
|
||||
|
||||
@Entity(tableName = "server_table")
|
||||
public class Server {
|
||||
|
||||
@PrimaryKey(autoGenerate = true)
|
||||
private int id;
|
||||
|
||||
@NonNull
|
||||
@ColumnInfo(name = "server_name")
|
||||
private String serverName;
|
||||
|
||||
@ColumnInfo(name = "server_host")
|
||||
private String serverHost;
|
||||
|
||||
@ColumnInfo(name = "username")
|
||||
private String username;
|
||||
|
||||
@ColumnInfo(name = "password")
|
||||
private String password;
|
||||
|
||||
public Server(@NonNull String serverName) {
|
||||
this.serverName = serverName;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getServerName() {
|
||||
return serverName;
|
||||
}
|
||||
|
||||
public void setServerName(String serverName) {
|
||||
this.serverName = serverName;
|
||||
}
|
||||
|
||||
public String getServerHost() {
|
||||
return serverHost;
|
||||
}
|
||||
|
||||
public void setServerHost(String serverHost) {
|
||||
this.serverHost = serverHost;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
}
|
44
app/src/main/java/net/schueller/peertube/database/Server.kt
Normal file
44
app/src/main/java/net/schueller/peertube/database/Server.kt
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Stefan Schüller <sschueller@techdroid.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package net.schueller.peertube.database
|
||||
|
||||
import android.os.Parcelable
|
||||
import androidx.room.PrimaryKey
|
||||
import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
|
||||
@Parcelize
|
||||
@Entity(tableName = "server_table")
|
||||
data class Server(
|
||||
|
||||
@PrimaryKey(autoGenerate = true)
|
||||
var id: Int = 0,
|
||||
|
||||
@ColumnInfo(name = "server_name")
|
||||
var serverName: String,
|
||||
|
||||
@ColumnInfo(name = "server_host")
|
||||
var serverHost: String? = null,
|
||||
|
||||
@ColumnInfo(name = "username")
|
||||
var username: String? = null,
|
||||
|
||||
@ColumnInfo(name = "password")
|
||||
var password: String? = null
|
||||
|
||||
) : Parcelable
|
@ -42,10 +42,17 @@ class AddServerFragment : Fragment() {
|
||||
|
||||
private val mServerViewModel: ServerViewModel by activityViewModels()
|
||||
|
||||
private var mServer: Server? = null
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
arguments?.let {
|
||||
mServer = it.getParcelable(SERVER_ARG)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
Log.d(TAG, "onCreateView")
|
||||
// Inflate the layout for this fragment
|
||||
mBinding = FragmentAddServerBinding.inflate(inflater, container, false)
|
||||
return mBinding.root
|
||||
}
|
||||
@ -53,22 +60,20 @@ class AddServerFragment : Fragment() {
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
// bind button click
|
||||
initServerEdit()
|
||||
|
||||
mBinding.addServerButton.setOnClickListener { view: View? ->
|
||||
mBinding.addServerButton.setOnClickListener {
|
||||
var formValid = true
|
||||
|
||||
hideKeyboard()
|
||||
|
||||
|
||||
if (mBinding.serverLabel.text.toString().isNullOrBlank()) {
|
||||
if (mBinding.serverLabel.text.toString().isBlank()) {
|
||||
mBinding.serverLabel.error = getString(R.string.server_book_label_is_required)
|
||||
Toast.makeText(context, R.string.invalid_url, Toast.LENGTH_LONG).show()
|
||||
formValid = false
|
||||
}
|
||||
|
||||
// validate url
|
||||
|
||||
mBinding.serverUrl.apply {
|
||||
APIUrlHelper.cleanServerUrl(text.toString())?.let {
|
||||
|
||||
@ -85,7 +90,7 @@ class AddServerFragment : Fragment() {
|
||||
|
||||
if (formValid) {
|
||||
mBinding.apply {
|
||||
val server = Server(serverLabel.text.toString())
|
||||
val server = Server(serverName = serverLabel.text.toString())
|
||||
|
||||
server.serverHost = serverUrl.text.toString()
|
||||
server.username = serverUsername.text.toString()
|
||||
@ -96,21 +101,26 @@ class AddServerFragment : Fragment() {
|
||||
}
|
||||
}
|
||||
|
||||
// Button testServerButton = mView.findViewById(R.id.testServerButton);
|
||||
// testServerButton.setOnClickListener(view -> {
|
||||
// Activity act = getActivity();
|
||||
// if (act instanceof ServerAddressBookActivity) {
|
||||
// ((ServerAddressBookActivity) act).testServer();
|
||||
// }
|
||||
// });
|
||||
|
||||
|
||||
mBinding.pickServerUrl.setOnClickListener {
|
||||
val intentServer = Intent(activity, SearchServerActivity::class.java)
|
||||
this.startActivityForResult(intentServer, PICK_SERVER)
|
||||
}
|
||||
}
|
||||
|
||||
private fun initServerEdit() {
|
||||
mServer?.let {
|
||||
mBinding.apply {
|
||||
serverLabel.setText(it.serverName)
|
||||
serverUrl.setText(it.serverHost)
|
||||
serverUsername.setText(it.username)
|
||||
serverPassword.setText(it.password)
|
||||
|
||||
addServerButton.text = getString(R.string.server_book_add_save_button)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
|
||||
@ -136,7 +146,16 @@ class AddServerFragment : Fragment() {
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val TAG = "AddServerFragment"
|
||||
const val PICK_SERVER = 1
|
||||
private const val TAG = "AddServerFragment"
|
||||
private const val PICK_SERVER = 1
|
||||
|
||||
private const val SERVER_ARG = "server"
|
||||
|
||||
fun newInstance(server: Server) = AddServerFragment().apply {
|
||||
arguments = Bundle().also {
|
||||
it.putParcelable(SERVER_ARG, server)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -1,10 +1,44 @@
|
||||
package net.schueller.peertube.utils
|
||||
|
||||
import android.content.Context
|
||||
import android.view.View
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.fragment.app.Fragment
|
||||
|
||||
fun View.gone() {
|
||||
this.visibility = View.GONE
|
||||
}
|
||||
|
||||
fun View.visible() {
|
||||
this.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
fun View.invisible() {
|
||||
this.visibility = View.INVISIBLE
|
||||
}
|
||||
|
||||
fun View.visibleIf(predicate: () -> Boolean) {
|
||||
when (predicate.invoke()) {
|
||||
true -> visible()
|
||||
else -> gone()
|
||||
}
|
||||
}
|
||||
|
||||
fun View.goneIf(predicate: () -> Boolean) {
|
||||
when (predicate.invoke()) {
|
||||
true -> gone()
|
||||
else -> visible()
|
||||
}
|
||||
}
|
||||
|
||||
fun View.invisibleIf(predicate: () -> Boolean) {
|
||||
when (predicate.invoke()) {
|
||||
true -> invisible()
|
||||
else -> visible()
|
||||
}
|
||||
}
|
||||
|
||||
fun Fragment.hideKeyboard(): Boolean {
|
||||
activity?.currentFocus?.let {
|
||||
val imm = context?.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
|
||||
|
10
app/src/main/res/drawable/ic_edit_24.xml
Normal file
10
app/src/main/res/drawable/ic_edit_24.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M3,17.25V21h3.75L17.81,9.94l-3.75,-3.75L3,17.25zM20.71,7.04c0.39,-0.39 0.39,-1.02 0,-1.41l-2.34,-2.34c-0.39,-0.39 -1.02,-0.39 -1.41,0l-1.83,1.83 3.75,3.75 1.83,-1.83z"/>
|
||||
</vector>
|
@ -1,6 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<androidx.cardview.widget.CardView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:card_view="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:clickable="true"
|
||||
@ -9,43 +11,52 @@
|
||||
card_view:cardElevation="0dp"
|
||||
card_view:cardUseCompatPadding="true">
|
||||
|
||||
<RelativeLayout
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:padding="12dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/serverLabelRow"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@style/Base.TextAppearance.AppCompat.Headline" />
|
||||
card_view:layout_constraintTop_toTopOf="parent"
|
||||
card_view:layout_constraintStart_toStartOf="parent"
|
||||
android:textAppearance="@style/Base.TextAppearance.AppCompat.Headline"
|
||||
tools:text="@tools:sample/lorem"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/serverUrlRow"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="0dp"
|
||||
android:textAppearance="@style/Base.TextAppearance.AppCompat.Subhead" />
|
||||
|
||||
</LinearLayout>
|
||||
card_view:layout_constraintTop_toBottomOf="@id/serverLabelRow"
|
||||
card_view:layout_constraintStart_toStartOf="parent"
|
||||
android:textAppearance="@style/Base.TextAppearance.AppCompat.Subhead"
|
||||
tools:text="@tools:sample/lorem"
|
||||
/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/sb_row_has_login_icon"
|
||||
android:src="@drawable/ic_baseline_account_circle_24"
|
||||
android:visibility="visible"
|
||||
android:contentDescription="@string/server_book_list_has_login"
|
||||
android:layout_width="24dp"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_height="wrap_content"/>
|
||||
android:layout_height="wrap_content"
|
||||
card_view:layout_constraintTop_toTopOf="parent"
|
||||
card_view:layout_constraintEnd_toEndOf="parent"
|
||||
android:contentDescription="@string/server_book_list_has_login"
|
||||
android:src="@drawable/ic_baseline_account_circle_24"
|
||||
/>
|
||||
|
||||
</RelativeLayout>
|
||||
<ImageView
|
||||
android:id="@+id/edit_icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
card_view:layout_constraintTop_toBottomOf="@id/sb_row_has_login_icon"
|
||||
card_view:layout_constraintEnd_toEndOf="parent"
|
||||
card_view:layout_constraintBottom_toBottomOf="parent"
|
||||
android:contentDescription="@string/server_book_list_has_login"
|
||||
android:src="@drawable/ic_edit_24"
|
||||
/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
@ -335,6 +335,7 @@
|
||||
<string name="server_book_add_username">Username</string>
|
||||
<string name="server_book_add_password">Password</string>
|
||||
<string name="server_book_add_add_button">Add</string>
|
||||
<string name="server_book_add_save_button">Save</string>
|
||||
<string name="server_book_list_has_login">Has Login</string>
|
||||
<string name="login_current_server_hint">Current Server</string>
|
||||
<string name="title_activity_server_address_book">Address Book</string>
|
||||
|
Loading…
Reference in New Issue
Block a user