如何以及在哪里拨打改造电话?

时间:2018-07-01 17:36:25

标签: android android-recyclerview kotlin retrofit2

我是一名初学者Android开发人员,试图通过构建电影数据库应用程序来学习移动开发。我正在用Kotlin编写我的应用程序,并使用Retrofit进行网络通话。我对如何调用以及如何使用tmdb API中的电影海报填充Recyclerview感到困惑。

这是我的界面:

interface APImovies {
    fun getMovies()
}

这是我与Retrofit服务器对象的主要活动:

class MainActivity() : AppCompatActivity() {

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

        val recyclerView = findViewById<RecyclerView>(R.id.recycler_view);
        recyclerView.layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
        recyclerView.layoutManager = GridLayoutManager(this, 3);
        recyclerView.adapter = PosterAdapter()
    }

    object RetrofitServer{
        val client: APImovies by lazy{
            val client = OkHttpClient.Builder().build()
            val retrofit = Retrofit
                    .Builder()
                    .baseUrl("https://api.themoviedb.org/3/movie/550?api_key=")
                    .addConverterFactory(GsonConverterFactory.create())
                    .client(client)
                    .build()
            retrofit.create(APImovies::class.java)
        }
    }
}

这是我的适配器,当前使用占位符图像填充Recyclerview:

class PosterAdapter() : RecyclerView.Adapter<PosterHolder>(){

    override fun getItemCount(): Int { return 300}

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PosterHolder{
        val layoutInflater = LayoutInflater.from(parent.context)
        val listItem = layoutInflater.inflate(R.layout.list_item, parent, false)
        return PosterHolder(listItem)
    }

    override fun onBindViewHolder(holder: PosterHolder, position: Int) {
        holder.view.movie_poster?.setImageResource(R.mipmap.beauty_and_the_beast_ver3)
        holder.view.movie_poster?.scaleType = ImageView.ScaleType.FIT_XY
    }
}

class PosterHolder(val view: View) : RecyclerView.ViewHolder(view), View.OnClickListener {
    var imageView: ImageView? = null

    fun PosterHolder(view: View){ this.imageView = view.findViewById<View>(R.id.movie_poster) as ImageView }

    override fun onClick(p0: View?) {}
}

2 个答案:

答案 0 :(得分:3)

我使用以下设置。看看这是否对您有帮助。

interface WebService {

    @GET
    fun getMovies(): Call<List<MyResponseObject>>

    companion object {
        fun create(): WebService {
            val client = OkHttpClient.Builder().build()
            val retrofit = Retrofit.Builder()
                    .baseUrl("YOUR_BASE_URL")
                    .addConverterFactory(GsonConverterFactory.create())
                    .client(client)
                    .build()

            return retrofit.create(WebService::class.java)
        }
    }
}

MainActivity中执行以下操作以进行网络通话

class MainActivity : AppCompatActivity() {
    private val webService = WebService.create()
    override fun onCreate(savedInstanceState: Bundle?, persistentState: 
    PersistableBundle?) {
        /*...*/
        fetchMovies()
    }

    private fun fetchMovies() {
        var call = webService.getMovies()
        call.enqueue(object : Callback<MyResponseObject> {
            override fun onFailure(call: Call<MyResponseObject>?, t: Throwable?) { }

            override fun onResponse(call: Call<MyResponseObject>?, response: Response<List<Class>>?) {
                if (response != null && response.isSuccessful) {
                    val myListData: MyResponseObject = response.body()
                    setUpRecyclerView(myListData) // The usual way of setting up a RecyclerView
                }
            }
        })
    }
}

这仅适用于初学者。我建议您使用Android体系结构组件和Dagger 2(用于依赖注入)研究MVVM体系结构。如 Nail Shaykhraziev

所述,由于您使用Kotlin,因此可以使用enter image description hereKotlin CoroutinesAndroidKTX进行DI的优势

答案 1 :(得分:-1)

我用这样的东西:

public final class ApiClient {

private static OkHttpClient sClient;
private static volatile MovieService movieService;

private ApiClient() {
}

public static MovieService getMovieService() {
    MovieService service = movieService;
    if (service == null) {
        synchronized (ApiClient.class) {
            service = movieService;
            if (service == null) {
                service = movieService = buildRetrofit().create(MovieService.class);
            }
        }
    }
    return service; // this is one of the implementation options singlton pattern. You can use some di tools(Kodein, Dagger)
}

private static Retrofit buildRetrofit() {

    return new Retrofit.Builder()
            .baseUrl(BuildConfig.BASE_URL)
            .client(getClient())
            .addConverterFactory(GsonConverterFactory.create(getGson()))
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .build();
}

private static Gson getGson() {
    return new GsonBuilder()
            .setLenient()
            .create();
}

private static OkHttpClient getClient() {
    OkHttpClient client = sClient;
    if (client == null) {
        synchronized (ApiClient.class) {
            client = sClient;
            if (client == null) {
                client = sClient = buildClient();
            }
        }
    }
    return client;
}

private static OkHttpClient buildClient() {
    return new OkHttpClient.Builder()
            .addInterceptor(TokenInterceptor.create())
            .build();
}}

在Presenter / Interactor / ViewModel调用改造服务方法之后:

ApiClient.movieService.popularMovies()
                .map { it.movies }
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .doOnSubscribe { view.showProgress }
                .doAfterTerminate { view.hideProgress }
                .subscribeBy(onSuccess = {
                   view.showMovies(it)
                }, onError = {
                   view.showErrors()
                })

关于活动/片段/视图:

class Activity : AppCompatActivity(), MovieView {

  override fun onCreate(savedInstanceState: Bundle?) {
      // your code
   }

  override fun showMovies(list: List<Movie>) {
     adapter.update(list)
   }
}