Useful Reminders

Django installation guide

Django is a Python web framework for full-stack web application development and server development that enables rapid development of secure and maintainable websites.  It is the most used framework for web development in Python programming language. As an open source project that supports the implementation of the most popular packages and Python tools, Django is a perfectly suitable choice for a mobile application backend.
Many global companies are using Django, like Instagram, National Geographic, Mozilla, Spotify, Pinterest, Disqus, Bitbucket, Eventbrite.

https://www.djangoproject.com

Installation

Download and Install Python from: https://www.python.org/downloads/

After that you can install Pipenv, a packaging tool for Python that simplifies dependency management. (https://realpython.com/pipenv-guide and https://pipenv.pypa.io)

In terminal/cmd window type: pip install pipenv

Download and Install VSC – Visual Studio Code editor: https://code.visualstudio.com
After installation, run VSC and in Extensions panel search for Python and install (if already isn’t installed): Python IntelliSense extension.

After that run terminal/cmd, create folder called storefront , enter the folder and type inside that folder:
pipenv install django

Open folder storefront in VSC (or drag&drop iside VSC from explorer)

In terminal/cmd type: pipenv shell
and after that type: django-admin startproject storefront . to start a new project.

To start development server, type in cmd: python manage.py runserver
Default port number is 8000. I you want to use other port number: python manage.py runserver 8800
Now we can enter address and port number we get as a result in the browser, for example: http://127.0.0.1:8000

In VSC open View menu end select Command Palette…
In search box type python interpreter and select Python: Select Interpreter
Click on Enter interpreter path …
Now type in terminal/cmd: pipenv --venv and copy the path into Enter interpreter path… field.
At the end of the path append: \Scripts\python (/bin/python if you are in Linux enviroment)
(something like, for example: C:\Users\G2.virtualenvs\storefront-QPOIJ0Ev\Scripts\python)

Now we can go to View menu in VSC and select Terminal and in terminal we can type: python manage.py runserver
(If you got error that running scripts is disabled on this system, you can try to open new terminal window clicking on + button in terminal window and type again python manage.py runserver. – defaultProfile is known not to work on the initial restored terminal. The same solution is if you sometime got error SyntaxError: invalid syntax)

second solution:
PowerShell by default restricts running scripts unless we change the execution policies. 
In VSC open View menu, select Command Palette and search settings.json. 
Select Open Workspace Settings(JSON) and add following lines:
{
    "terminal.integrated.profiles.windows": {
        "PowerShell": {
          "source": "PowerShell",
          "icon": "terminal-powershell",
          "args": ["-ExecutionPolicy", "Bypass"]
        }
      },
      "terminal.integrated.defaultProfile.windows": "PowerShell",
}
After that we need to restart VS Code and the Terminal. 

For more info go to: https://docs.djangoproject.com/en/4.1/intro/install/ and https://www.youtube.com/watch?v=rHux0gMZ3Eg

Glide library in Kotlin

Glide is fast and efficient image loading library for android. Using Glide library we can download, decode and display images, videos or animated GIFs, resize downloaded images, show placeholder while loading image, show pre-defined images when there is any error while downloading image, apply animation while loading image and use cache for offline viewing.

First, in app/build.gradle file we have to add:

implementation 'com.github.bumptech.glide:glide:4.12.0'

And in AndroidManifest.xml file we need to add internet permission:

<uses-permission android:name="android.permission.INTERNET"/>

For loading pictures into ImageView we have to create ImageView element in xml Layout with ID:

<ImageView
  android:id="@+id/imageView" 
  android:layout_width="200dp"
  android:layout_height="200dp"/>

And in MainActivity.kt we can use basic code:

Glide.with(this)
   .load("Your_Image_URL")
   .into(imageView)

Methods that we can use with Glide are:

  • .placeholder("Placeholder Image URL") – to show placeholder while image is being loaded.
  • .error(“Error_Image_URL”) – to show error placeholder.
  • .fallback(“Fallback_Image_URL”) – if requested url/model is null we use fallback placeholder.
  • .override(150, 150) – If we want to resize downloaded image.
  • .centerCrop(), . fitCenter(), .circleCrop() – several in-built transformations.

We can apply transition from a placeholder to newly loaded image, or from a thumbnail to full size image easly by using many transition available to glide. For example:

val factory = DrawableCrossFadeFactory.Builder().setCrossFadeEnabled(true).build()
Glide.with(this)
  .load("Your_Image_URL")
  .transition(withCrossFade(factory))
  .into(imageView)

We cannot do the cross fade between two different images that are loaded with different requests. Glide by default will cancel any existing requests when you start a new load into an existing View or Target. As a result, if you want to load two different images and cross fade between them, you cannot do so with Glide directly. Instead, the easiest way to cross fade across two different images loaded in two separate requests is to use ViewSwitcher containing two ImageViews. Load the first image into the result of getNextView(). Then load the second image into the next result of getNextView() and use a RequestListener to call showNext() when the second image load finishes.

see Glide documentation for more info

Caching in Glide:

When loading image, Glide first checks if image already exist in memory, in case that this image is displayed in another View right now and to see if this image is recently loaded and is it still in memory?
After that Glide check if image is already stored in disk to see if this image has been decoded, transformed, and written to the disk cache before.
If image is neither found in memory nor in disk, Glide sends request to fetch image from remote url.

Using diskCacheStrategy method, we apply disk caching. Value passed in method defines how disk caching is configured:

  • diskCacheStrategy.ALL caches remote data with both DATA and RESOURCE, and local data with RESOURCE only.
  • diskCacheStrategy.AUTOMATIC is set by default and it tries to choose strategy using DataFetcher and EncodeStrategy.
  • diskCacheStrategy.DATA writes retrieved data directly to disk cache before it is decoded.
  • diskCacheStrategy.NONE doesn’t save data to cache and
  • diskCacheStrategy.RESOURCE writes data to disk after it is decoded.

For example, we can apply disk caching for remote data with both DATA and RESOURCE:

Glide.with(CONTEXT)
  .load(URL)
  .diskCacheStrategy(DiskCacheStrategy.ALL)
  .into(imageView)

If we want to load data only from the cache, we use: .onlyRetrieveFromCache(true)

If we want to skip memory or disk caching (or both) we can use: .diskCacheStrategy(DiskCacheStrategy.NONE) or .skipMemoryCache(true)

End now our code for loading picture into ImageView can look something like this:

val imageUrl = "https://glideapps.com/images/cover-logo.png"
val factory = DrawableCrossFadeFactory.Builder().setCrossFadeEnabled(true).build()

Glide.with(this)
  .load(imageUrl)
  .placeholder(R.mipmap.ic_launcher)
  .error(R.drawable.ic_error)
  .fallback(android.R.drawable.ic_menu_slideshow)
  .circleCrop()
  .override(150, 150) // dimensions are in pixels
  .transition(withCrossFade(factory))
  .diskCacheStrategy(DiskCacheStrategy.ALL)
  .into(imageView)

viewBinding

View Binding is a part of Android Jetpack and allows us to more easily write code that interacts with views. Once view binding is enabled in a module, it generates a binding class for each XML layout file present in that module.

Each binding class contains references to the root view and all views that have an ID. The name of the binding class is generated by converting the name of the XML file to Pascal case and adding the word “Binding” to the end. For example, if a layout file is called activity_main.xml the genereted binding class will be called ActivityMainBinding

Instead using findViewById() method we can use viewBinding to access elements in Kotlin .xml file.

First we have to add viewBinding true in app/build.gradle file:

android {
  // …
   buildFeatures {
       viewBinding = true
   }
 }

To set up an instance of the binding class for use with an activity, in MainActivity.kt onCreate() method we have to write code:

class MainActivity : AppCompatActivity() {

   private lateinit var binding: ActivityMainBinding

   override fun onCreate(savedInstanceState: Bundle?) {
      super.onCreate(savedInstanceState)

         binding = ActivityMainBinding.inflate(layoutInflater)
         val view = binding.root

      setContentView(view)
   }
 }

We can now use the instance of the binding class to reference any of the views, for example:

binding.tv_title.text = "Title"
binding.name.text = viewModel.name
binding.button.setOnClickListener { viewModel.userClicked() }
binding.imageButton.visibility = View.VISIBLE

View binding has important advantages over using findViewById:
Since view binding creates direct references to views, there’s no risk of a null pointer exception due to an invalid view ID. Additionally, when a view is only present in some configurations of a layout, the field containing its reference in the binding class is marked with @Nullable.
The fields in each binding class have types matching the views they reference in the XML file. This means that there’s no risk of a class cast exception.
Incompatibilities between layout and code will result in build failing at compile time rather than at runtime.