Skip to content

Instantly share code, notes, and snippets.

@sagar-viradiya
Last active August 17, 2021 17:55
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 7 You must be signed in to fork a gist
  • Save sagar-viradiya/64b6a8331b3f4d436ae499b9700ac1f4 to your computer and use it in GitHub Desktop.
Save sagar-viradiya/64b6a8331b3f4d436ae499b9700ac1f4 to your computer and use it in GitHub Desktop.
DevFest India 2020 Day 1 - Main Acitvity UI
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"
android:background="@color/backgroundColor"
tools:context=".MainActivity">
<androidx.core.widget.ContentLoadingProgressBar
android:id="@+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
style="?android:attr/progressBarStyle" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
android:orientation="vertical"
android:visibility="gone"
tools:visibility="visible"
tools:listitem="@layout/movie_item_layout" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/errorView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:visibility="gone"
tools:visibility="visible"
android:fontFamily="@font/roboto"
android:text="@string/error_msg"/>
</FrameLayout>
@RB-93
Copy link

RB-93 commented Oct 16, 2020

Do we have to manually create some files as in this a layout file at line 25, font at line 35 and string at line 36 missing?

@sagar-viradiya
Copy link
Author

Hey Rohit, You only have to create string resources. The rest all will be taken care. Hope to have gr8 DevFest India!

@RB-93
Copy link

RB-93 commented Oct 17, 2020

Got it! Thanks 🙂

@GauravChoudhary8411
Copy link

Screenshot (1394)
The items are not being displayed correctly but in the preview of movie_list_item everything is just as it should be

@RB-93
Copy link

RB-93 commented Oct 18, 2020

@GauravChoudhary4811
Upload your XML file here that would help, might be your constraints/margins, text attributes are not set properly.

@GauravChoudhary8411
Copy link

@GauravChoudhary4811
Upload your XML file here that would help, might be your constraints/margins, text attributes are not set properly.

Movie_list_item

<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
app:cardCornerRadius="8dp"
app:cardElevation="4dp"
android:paddingBottom="16dp"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto">

<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:layout_width="wrap_content"
        android:id="@+id/movieposter"
        android:layout_height="0dp"
        android:scaleType="centerCrop"
        app:layout_constraintDimensionRatio="h,16:9"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:ignore="MissingConstraints"
        tools:src="@tools:sample/backgrounds/scenic" />

    <TextView
        android:id="@+id/movieTitle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:text="Movie Title"
        android:textAppearance="@style/TextAppearance.MaterialComponents.Subtitle1"
        app:layout_constraintTop_toBottomOf="@+id/movieposter"
        tools:ignore="MissingConstraints"
        tools:layout_editor_absoluteX="16dp" />

    <TextView
        android:id="@+id/avgVoting"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:drawableStart="@drawable/ic_baseline_thumb_up_24"
        android:drawablePadding="8dp"
        android:text="3.4"
        android:textAppearance="@style/TextAppearance.AppCompat.Display1"
        app:layout_constraintTop_toBottomOf="@+id/movieposter"
        tools:ignore="MissingConstraints"
        tools:layout_editor_absoluteX="300dp" />

    <TextView
        android:id="@+id/releaseDate"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="12th Dec 2020"
        android:textAppearance="@style/TextAppearance.AppCompat.Headline"
        tools:layout_editor_absoluteX="16dp"
        tools:layout_editor_absoluteY="268dp"
        tools:ignore="MissingConstraints"
        app:layout_constraintTop_toBottomOf="@id/movieTitle"/>

    <TextView
        android:id="@+id/totalVotes"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:text="1000"
        app:layout_constraintTop_toBottomOf="@+id/avgVoting"
        tools:ignore="MissingConstraints"
        tools:layout_editor_absoluteX="347dp" />


</androidx.constraintlayout.widget.ConstraintLayout>

</com.google.android.material.card.MaterialCardView>

@GauravChoudhary8411
Copy link

I am also getting an error in MovieResponse.kt

@RB-93
Copy link

RB-93 commented Oct 18, 2020

@GauravChoudhary8411

You should pass @tools:src value in ImageView as sample/avatar. That would place a profile like mono for the image.

For each TextView, you used tools:ignore="MissingConstraints" which you shouldn't do if you are using ConstraintLayout as ViewGroup.
You have to set atleast three position constraints
like you did for ImagView as

app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"

...there are more such constraints that you may need to correctly position your views. See official docs.

@sagar-viradiya
Copy link
Author

@RB-93 for answering the question. @GauravChoudhary8411 Let me know if this resolves your problem or not.

@RB-93
Copy link

RB-93 commented Oct 18, 2020

@GauravChoudhary8411
Could you please mention error(s) in the file.

@GauravChoudhary8411
Copy link

GauravChoudhary8411 commented Oct 18, 2020

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.devfest.india.bmsclone/com.example.book.MainActivity}: java.lang.IllegalArgumentException: HTTP method annotation is required (e.g., @get, @post, etc.).
for method MovieService.getMovies
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3270)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
Caused by: java.lang.IllegalArgumentException: HTTP method annotation is required (e.g., @get, @post, etc.).
for method MovieService.getMovies
at retrofit2.Utils.methodError(Utils.java:54)
at retrofit2.Utils.methodError(Utils.java:43)
at retrofit2.RequestFactory$Builder.build(RequestFactory.java:185)
at retrofit2.RequestFactory.parseAnnotations(RequestFactory.java:67)
at retrofit2.ServiceMethod.parseAnnotations(ServiceMethod.java:26)
at retrofit2.Retrofit.loadServiceMethod(Retrofit.java:202)
at retrofit2.Retrofit$1.invoke(Retrofit.java:160)
at java.lang.reflect.Proxy.invoke(Proxy.java:1006)
at $Proxy0.getMovies(Unknown Source)
at com.example.book.MainActivity.fetchMovies(MainActivity.kt:24)
at com.example.book.MainActivity.onCreate(MainActivity.kt:18)
at android.app.Activity.performCreate(Activity.java:7802)
at android.app.Activity.performCreate(Activity.java:7791)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1299)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3245)
... 11 more
2020-10-18 12:43:22.971 13962-13962/com.devfest.india.bmsclone I/Process: Sending signal. PID: 13962 SIG: 9

@GauravChoudhary8411
Copy link

GauravChoudhary8411 commented Oct 18, 2020

@RB-93 the app is not opening because of these errors in the Main Activity
at com.example.book.MainActivity.fetchMovies(MainActivity.kt:24)
at com.example.book.MainActivity.onCreate(MainActivity.kt:18)

@RB-93
Copy link

RB-93 commented Oct 18, 2020

From your error log,
java.lang.IllegalArgumentException: HTTP method annotation is required (e.g., @get, @post, etc.). for method MovieService.getMovies

Please check that you have mentioned @GET(discover/movie) annotation or not before getMovies() method in MovieSevice.kt file. It will be required to get movie data from that server directory whenever the request is sent to API.

@GauravChoudhary8411
Copy link

GauravChoudhary8411 commented Oct 18, 2020

@RB-93 I mentioned it Could you please send your code?

@RB-93
Copy link

RB-93 commented Oct 18, 2020

This is my code for MovieService.kt file.

interface MovieService {

    @GET("discover/movie")
    fun getMovies(@Query("api_key") key: String): Call<MovieResponse>
}

@GauravChoudhary8411
Copy link

@RB-93 I did the exact same thing. Please send the code for MainActivity

@RB-93
Copy link

RB-93 commented Oct 18, 2020

This is my code for the MainActivity.kt file.

class MainActivity : AppCompatActivity() {

    private lateinit var viewModel: MainViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        setupViewModel()
        observeViewModel()
    }

    private fun setupViewModel() {
        showProgress()

        viewModel = ViewModelProvider(
            this, MainViewModelFactory(
                NetworkHelper(this),
                MovieRepositoryImpl(
                    MovieDatabase.getInstance(this).movieDao(),
                    RetrofitBuilder.buildService()
                )
            )
        )[MainViewModel::class.java]
        viewModel.onCreate()
    }

    private fun observeViewModel() {
        viewModel.movieResponse.observe(this, Observer {
            showMovies(it.results)
            hideProgress()
        })

        viewModel.errorResponse.observe(this, Observer {
            showErrorMessage(it)
            hideProgress()
        })
    }

    private fun showMovies(movies: List<Movie>) {
        recyclerView.visibility = View.VISIBLE
        recyclerView.setHasFixedSize(true)
        recyclerView.itemAnimator = DefaultItemAnimator()
        recyclerView.adapter = MoviesAdapter(movies)
    }

    private fun showErrorMessage(errorMessage: String?) {
        errorView.visibility = View.VISIBLE
        errorView.text = errorMessage
    }

    private fun hideProgress() {
        progressBar.visibility = View.GONE
    }

    private fun showProgress() {
        progressBar.visibility = View.VISIBLE
    }
}

Let us know if you find any issues.

@soni1468
Copy link

image

The image is not getting shown in the card even though it's coming fine in preview.

image

below is the movie_item_layout.xml for reference:

<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
app:cardCornerRadius="8dp"
app:cardElevation="4dp"
app:contentPaddingBottom="16dp"
xmlns:tools="http://schemas.android.com/tools">

<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/moviePoster"
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:scaleType="centerCrop"
        app:layout_constraintDimensionRatio="h,16:9"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:src="@tools:sample/avatars" />

    <TextView
        android:id="@+id/movieTitle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginTop="16dp"
        android:textAppearance="@style/TextAppearance.MaterialComponents.Headline6"
        app:layout_constraintBottom_toTopOf="@+id/releaseDate"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/moviePoster"
        tools:text="Movie Title" />

    <TextView
        android:id="@+id/releaseDate"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:textAppearance="@style/TextAppearance.MaterialComponents.Subtitle2"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/movieTitle"
        tools:text="07th July 1996" />

    <TextView
        android:id="@+id/avgVoting"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:layout_marginEnd="16dp"
        android:drawableStart="@drawable/ic_baseline_thumb_up_24"
        android:drawablePadding="8dp"
        android:textAppearance="@style/TextAppearance.AppCompat.Medium"
        app:layout_constraintBottom_toTopOf="@+id/totalVotes"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/moviePoster"
        tools:text="3.4" />

    <TextView
        android:id="@+id/totalVotes"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="16dp"
        android:layout_marginBottom="3dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/avgVoting"
        tools:text="1468" />
</androidx.constraintlayout.widget.ConstraintLayout>

</com.google.android.material.card.MaterialCardView>

@sagar-viradiya
Copy link
Author

@soni1468 As I already mentioned in the session, tools namespace is only for preview purposes. You have to either use android namspace and use image stored locally in your app or load it from a remote sever. Niharika and Shreyank did it in the 2nd session.

@sagar-viradiya
Copy link
Author

@RB-93 Thanks for constant support in answering queries.

@RB-93
Copy link

RB-93 commented Oct 18, 2020

@sagar-viradiya

Thanks to you and the team, made possible these talks, explained and covered all the aspects to create wonderful app.
Learnt a lot! 😀
And for support, always ready for it any time. 🙂

@soni1468
Copy link

I am also facing the same exact issue.
Not able to get the image using static links even though internet permission is added.

@ArkaprabhaChakraborty
Copy link

I am also facing the same exact issue.
Not able to get the image using static links even though internet permission is added.

Well I fixed it ...... It was a simple error in logic from my end .... I typed wrap_content where it should be match_parent

@GauravChoudhary8411
Copy link

Could you provide the gist of the whole app?

@RB-93
Copy link

RB-93 commented Oct 26, 2020

Hi,
It's available on DevFest India resources link page under Mobile track.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment