简体   繁体   中英

How to load data from json in expandable listview using retrofit?

I want to load question and answer in expandable listview from json using retrofit library. I dont know how to do this. Find me a solution. Here is the two model class i am using.

public class QuestionResult {

boolean IsSuccess;
List<QuestionsModel> question;

public boolean isSuccess() {
    return IsSuccess;
}

public List<QuestionsModel> getQuestion() {
    return question;
}
}

And

public class QuestionsModel {
private int q_id;
private int category_id;
private String question;
private String answer;

public int getQ_id() {
    return q_id;
}

public int getCategory_id() {
    return category_id;
}

public String getQuestion() {
    return question;
}

public String getAnswer() {
    return answer;
}
}

Here is my Activity

public class QuestionBank extends AppCompatActivity {

@InjectView(R.id.ques_type_spinner)
Spinner courseSpinner;
@InjectView(R.id.home_btn_qbank)
Button homeButton;
@InjectView(R.id.no_questions)
TextView textView;
@InjectView(R.id.ques_ans_listview)
ExpandableListView listView;

List<String> courseNames;
ArrayAdapter<String> courseAdapter;
ExpandableListAdapter listAdapter;
List<QuestionResult> resultList;
ProgressDialog progress;
int selectedPosition;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_question_bank);
    ButterKnife.inject(this);
    StatusBarTheme.setStatusBarColor(this);

    showCourseCategory();
    homeButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            finish();
        }
    });

    courseSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
            selectedPosition = courseSpinner.getSelectedItemPosition() + 1;
            Log.d("cat_id ", " " + selectedPosition);
            loadQuestions(selectedPosition);
        }

        @Override
        public void onNothingSelected(AdapterView<?> parent) {

        }
    });
}

private void loadQuestions(final int selectedPosition) {

    ApiInterface apiInterface = ApiClient.getClient(this).create(ApiInterface.class);
    Call<QuestionResult> call = apiInterface.loadQuesAndAnswers(selectedPosition);

    call.enqueue(new Callback<QuestionResult>() {
        @Override
        public void onResponse(Call<QuestionResult> call, Response<QuestionResult> response) {

            List<QuestionsModel> questionsModelList = response.body().getQuestion();
            if (questionsModelList != null) {

                listAdapter = new ExpandListAdapter(QuestionBank.this, questionsModelList, selectedPosition);
                listView.setAdapter(listAdapter);

            } else {
                listView.setVisibility(View.GONE);
                textView.setVisibility(View.VISIBLE);
            }

        }

        @Override
        public void onFailure(Call<QuestionResult> call, Throwable t) {

        }
    });
}

private void showCourseCategory() {

    ApiInterface apiInterface = ApiClient.getClient(this).create(ApiInterface.class);
    Call<CategoryResult> call = apiInterface.loadCourseTitle();
    progress = new ProgressDialog(QuestionBank.this);
    progress.setMessage("Loading.. Please wait");
    progress.show();

    call.enqueue(new Callback<CategoryResult>() {
        @Override
        public void onResponse(Call<CategoryResult> call, Response<CategoryResult> response) {

            if (progress.isShowing()) {
                progress.dismiss();
            }

            if (response.body().isSuccess() && response.body().getCategory() != null) {
                response.body().getCategory();
                courseNames = new ArrayList<>();
                for (CourseType courseType : response.body().getCategory()) {
                    courseNames.add(courseType.getCategory_title());
                }
                loadSpinner(courseNames);
            }
        }

        @Override
        public void onFailure(Call<CategoryResult> call, Throwable t) {

        }

    });
}

private void loadSpinner(List<String> educationTypeList) {
    courseAdapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, educationTypeList);
    courseAdapter.setDropDownViewResource(android.R.layout.simple_list_item_checked);
    courseSpinner.setAdapter(courseAdapter);
}
}

Here is the complete code. Change it for your purposes. If anything will happen you can write comment i will answer.

Application.class

public class Application extends Application{

    private static Application instance;
    private I_Requests iWebEndpoint;

    @Override
    public void onCreate() {
        super.onCreate();
        instance = this;
    }

    public static Application i() {
        return instance;
    }


    public I_Requests w() {
        if(this.iWebEndpoint == null){
            initRetrofit();
        }
        return iWebEndpoint;
    }

    private void initRetrofit(){

        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        OkHttpClient client = new OkHttpClient
                .Builder()
                .addInterceptor(interceptor)
                .readTimeout(1, TimeUnit.MINUTES)
                .writeTimeout(1, TimeUnit.MINUTES)
                .connectTimeout(1, TimeUnit.MINUTES)
                .build();

        client.readTimeoutMillis();

        this.iWebEndpoint = new Retrofit.Builder()
                .baseUrl(I_Requests.address)
                .client(client)
                .addConverterFactory(JacksonConverterFactory.create())
                .build()
                .create(I_Requests.class);
    }
}

JacksonConverterFactory.class

import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
import com.fasterxml.jackson.databind.ObjectWriter;

import java.lang.annotation.Annotation;
import java.lang.reflect.Type;

import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.Converter;
import retrofit2.Retrofit;

/**
 * A {@linkplain Converter.Factory converter} which uses Jackson.
 * <p>
 * Because Jackson is so flexible in the types it supports, this converter assumes that it can
 * handle all types. If you are mixing JSON serialization with something else (such as protocol
 * buffers), you must {@linkplain Retrofit.Builder#addConverterFactory(Converter.Factory) add this
 * instance} last to allow the other converters a chance to see their types.
 */
public final class JacksonConverterFactory extends Converter.Factory {
  /** Create an instance using a default {@link ObjectMapper} instance for conversion. */
  public static JacksonConverterFactory create() {
    return create(new ObjectMapper());
  }

  /** Create an instance using {@code mapper} for conversion. */
  public static JacksonConverterFactory create(ObjectMapper mapper) {
    return new JacksonConverterFactory(mapper);
  }

  private final ObjectMapper mapper;

  private JacksonConverterFactory(ObjectMapper mapper) {
    if (mapper == null) throw new NullPointerException("mapper == null");
    this.mapper = mapper;
  }

  @Override
  public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
      Retrofit retrofit) {
    JavaType javaType = mapper.getTypeFactory().constructType(type);
    ObjectReader reader = mapper.reader(javaType);
    return new JacksonResponseBodyConverter<>(reader);
  }

  @Override
  public Converter<?, RequestBody> requestBodyConverter(Type type,
      Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
    JavaType javaType = mapper.getTypeFactory().constructType(type);
    ObjectWriter writer = mapper.writerWithType(javaType);
    return new JacksonRequestBodyConverter<>(writer);
  }
}

JacksonRequestBodyConverter.class

import com.fasterxml.jackson.databind.ObjectWriter;

import java.io.IOException;

import okhttp3.MediaType;
import okhttp3.RequestBody;
import retrofit2.Converter;

final class JacksonRequestBodyConverter<T> implements Converter<T, RequestBody> {
  private static final MediaType MEDIA_TYPE = MediaType.parse("application/json; charset=UTF-8");

  private final ObjectWriter adapter;

  JacksonRequestBodyConverter(ObjectWriter adapter) {
    this.adapter = adapter;
  }

  @Override public RequestBody convert(T value) throws IOException {
    byte[] bytes = adapter.writeValueAsBytes(value);
    return RequestBody.create(MEDIA_TYPE, bytes);
  }
}

JacksonResponseBodyConverter.class

import com.fasterxml.jackson.databind.ObjectReader;

import java.io.IOException;

import okhttp3.ResponseBody;
import retrofit2.Converter;

final class JacksonResponseBodyConverter<T> implements Converter<ResponseBody, T> {
  private final ObjectReader adapter;

  JacksonResponseBodyConverter(ObjectReader adapter) {
    this.adapter = adapter;
  }

  @Override public T convert(ResponseBody value) throws IOException {
    try {
      return adapter.readValue(value.charStream());
    } finally {
      value.close();
    }
  }
}

I_Request.interface

import java.util.ArrayList;

import manqaro.com.projectz.ServerSide.Response.TestData;
import manqaro.com.projectz.ServerSide.Response.TestResponse;
import retrofit2.Call;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.POST;

public interface I_Requests {

    //PUT HERE YOUR SERVER MAIN ADDRES
    String address = "http://goto.xcodes.club";

    //SAMPLE EXAMPLE OF POST TYPE , YOU SHOULD CHANGE EVERYTHING YOU WANT.
    //IN THIS EXAMPLE YOU WILL GET JSON DATA WHICH WILL BE CONVERTED TO JAVA OBJECT.
    @FormUrlEncoded
    //Here YOU HAVE TO GIVE ADDRESS TO SPECIFIC CALL
    @GET("/api/v1/objects/")
    Call<TestResponse<ArrayList<TestData>>> login(
    );


    @FormUrlEncoded
    @POST("/api/v1/objects/")
    Call<TestResponse<ArrayList<TestData>>> register(
    );
}

TestResponse.class

import com.fasterxml.jackson.annotation.JsonProperty;

/**
 * Created by ArsenSench on 11/9/2016.
 */

public class TestResponse<T> {
    @JsonProperty("status")
    public int status;

    @JsonProperty("message")
    public String message;

    @JsonProperty("data")
    public T data;

}

TestData.class

import com.fasterxml.jackson.annotation.JsonProperty;


/**
 * Created by ArsenSench on 11/9/2016.
 */

public class TestData extends {

    @JsonProperty("id")
    public int id;

    @JsonProperty("name")
    public String name;

    @JsonProperty("description")
    public String description;

    @JsonProperty("avatar")
    public String avatar;

    @JsonProperty("rate")
    public int rate;
}

ServerCalls.class

import android.content.Context;
import android.util.Log;
import android.widget.Toast;
import java.util.ArrayList;
import manqaro.com.projectz.ServerSide.Application.Tickle_Application;
import manqaro.com.projectz.ServerSide.Response.TestData;
import manqaro.com.projectz.ServerSide.Response.TestResponse;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

/**
 * Created by ArsenSench on 11/9/2016.
 */

public class ServerCalls {
    Context context;
    public ServerCalls(Context context){
        this.context = context;
    }

    public void testCallBack(){

       Tickle_Application.i().w().login().enqueue(new Callback<TestResponse<ArrayList<TestData>>>() {
           @Override
           public void onResponse(Call<TestResponse<ArrayList<TestData>>> call, Response<TestResponse<ArrayList<TestData>>> response) {
               if(response.code()==200){
                   if(response.body().status==200){

                       Toast.makeText(context, response.body().data.get(0).name, Toast.LENGTH_SHORT).show();

                   }

                   else{
                       Toast.makeText(context, "No Name", Toast.LENGTH_SHORT).show();
                   }
               }

               else{

                   Toast.makeText(context, "No Connection", Toast.LENGTH_SHORT).show();
               }
           }

           @Override
           public void onFailure(Call<TestResponse<ArrayList<TestData>>> call, Throwable t) {
               Toast.makeText(context, t.getCause().getMessage(), Toast.LENGTH_SHORT).show();
               Log.e("jex", "onFailure: " + t.getCause().getMessage() );
           }
       });
        }
        }

TestActivity.activity

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;

import manqaro.com.projectz.R;
import manqaro.com.projectz.ServerSide.Main.ServerCalls;

public class TestActivity extends AppCompatActivity {
    ServerCalls sc = new ServerCalls(this);
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);
    }

    public void clickThatShit(View view){

        sc.testCallBack();
    }
}

Manifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="your.package.name">

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

    <application
        android:name=".Application"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:largeHeap="true"
        android:supportsRtl="true"
        android:theme="@style/AppTheme"
        tools:replace="android:icon">
        <activity
            android:name=".TestActivity">

        </activity>

    </application>

</manifest>

build.gradle(module app) Include these dependencies in yourdependencies

    compile 'com.squareup.retrofit2:retrofit:2.0.0'
    compile 'com.squareup.okhttp3:logging-interceptor:3.2.0'
    compile 'com.fasterxml.jackson.core:jackson-databind:2.7.3'
    compile 'com.fasterxml.jackson.core:jackson-annotations:2.7.3'

Include this lines in your android{} block

 packagingOptions {
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/NOTICE'
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM