I'm trying to pass the data from my json array to tableview (its the only one that I found that has an example similar to mine compared to listview) and my app always crashes when I always click my show button and I'm lost because of it.
heres my code :
my code for getting the data from jsonarray:
public class bTSQLClient extends AppCompatActivity {
////for populating the table
private final Context context;
private SimpleTableDataAdapter adapter;
TableView<String[]> tableView;
TableHelper tableHelper;
//getting the current sysID use in protected params
private static final String KEY_SYS_ID = "sys_id";
private int sys_Id = SharedPrefManager.getInstance(this).getUserid();
//View Branch
private static final String KEY_VB_ID = "branchid";
private static final String KEY_VB_USER = "username";
private static final String KEY_VB_PASSWORD = "password";
private static final String KEY_VB_NAME = "branchname";
private static final String KEY_VB_SYSID = "sys_id";
private static final String KEY_VB_CREATED = "created";
private static final String KEY_VB_UT = "user_type";
private int viewBranchID;
private String viewBranchUser;
private String viewBranchPassword;
private String viewBranchName;
private int viewBranchSYSID;
private int viewBranchCreated;
private String viewBranchUT;
//for populating the table
public bTSQLClient(Context context) {
this.context = context;
}
/**
* get Branch Data Operation table populate
*/
public void retrieve(final TableView tableView){
final ArrayList<branchlist> branchList = new ArrayList<>();
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Request.Method.POST,
Constants.viewbranches_url, null,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
JSONObject jsonObject;
branchlist b;
try
{
for (int i = 0; i < response.length(); i++)
{
jsonObject = response.getJSONObject(i);
//viewBranchID = jsonObject.getInt(KEY_VB_ID);
viewBranchUser = jsonObject.getString(KEY_VB_USER);
//viewBranchPassword = jsonObject.getString(KEY_VB_PASSWORD);
viewBranchName = jsonObject.getString(KEY_VB_NAME);
//viewBranchSYSID = jsonObject.getInt(KEY_VB_SYSID);
//viewBranchCreated = jsonObject.getInt(KEY_VB_CREATED);
//viewBranchUT = jsonObject.getString(KEY_VB_UT);
b = new branchlist();
//b.setBranchid(viewBranchID);
b.setUsername(viewBranchUser);
//b.setPassword(viewBranchPassword);
b.setBranchname(viewBranchName);
//b.setSys_id(viewBranchSYSID);
//b.setCreated(viewBranchCreated);
//b.setUser_type(viewBranchUT);
branchList.add(b);
}
//set to table view
adapter = new SimpleTableDataAdapter(context,new TableHelper(context).returnBranchViewArray(branchList));
tableView.setDataAdapter(adapter);
} catch (JSONException e)
{
//e.printStackTrace();
Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG).show();
Log.e ( "response", "" + response );
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getApplicationContext(), error.getMessage(), Toast.LENGTH_LONG).show();
Log.e ( "response", "" + error );
}
}) {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
params.put(KEY_SYS_ID, String.valueOf(sys_Id));
return params;
}
};
RequestHandler.getInstance(this).addToRequestQueue(jsonArrayRequest);
}
}
Heres the TableHelper Class
public class TableHelper {
Context context;
private String[] branchViewHeader = {"Branch Name", "Username"};
private String[][] branchView;
public TableHelper(Context context){
this.context = context;
}
public String[] getBranchViewHeader()
{
return branchViewHeader;
}
public String[][] returnBranchViewArray(ArrayList<branchlist> branchList)
{
branchView = new String[branchList.size()][2];
branchlist b;
for(int i = 0; i<branchList.size();i++){
b = branchList.get(i);
branchView[i][0]=b.getBranchname();
branchView[i][1]=b.getUsername();
}
return branchView;
}
}
branchlist class
public class branchlist {
private int branchid;
private String username;
private String password;
private String branchname;
private int sys_id;
private int created;
private String user_type;
public int getBranchid(){
return branchid;
}
public void setBranchid(int branchid){
this.branchid = branchid;
}
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;
}
public String getBranchname(){
return branchname;
}
public void setBranchname(String branchname){
this.branchname = branchname;
}
public int getSys_id(){
return sys_id;
}
public void setSys_id(int sys_id){
this.sys_id = sys_id;
}
public int getCreated(){
return created;
}
public void setCreated(int created){
this.created = created;
}
public String getUser_type(){
return user_type;
}
public void setUser_type(String user_type){
this.user_type = user_type;
}
public String toString(){
return branchname;
}
}
heresmy code for branch(the code that the bTSQLClient will pass to)
public class branch extends AppCompatActivity {
////for populating the table
private SimpleTableDataAdapter adapter;
TableView<String[]> tableView;
TableHelper tableHelper;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_branch);
if (!SharedPrefManager.getInstance(this).isLoggedIn()) {
finish();
startActivity(new Intent(this, login.class));
return;
}
//for populating table
tableHelper = new TableHelper(this);
tableView = (TableView<String[]>) findViewById(R.id.tableView);
tableView.setColumnCount(2);
tableView.setHeaderBackgroundColor(Color.parseColor("#2ecc71"));
tableView.setHeaderAdapter(new SimpleTableHeaderAdapter(this,tableHelper.getBranchViewHeader()));
}
/**
* Show populated Table
*/
public void onTableshow(View view){ // The Error is right here (bTSQLClient is the above code)
new bTSQLClient(branch.this).retrieve(tableView);
}
/**
* goto Popup on Add Branch Account
*/
public void onAddBranch(View view){
startActivity(new Intent(branch.this,popup_addbranch.class));
}
/**
* Menu Signout
*/
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
int id = item.getItemId();
switch (id) {
case R.id.menuLogout:
SharedPrefManager.getInstance(this).isLoggedOut();
finish();
startActivity(new Intent(this, login.class));
break;
}
return true;
}
/**
* Back to dashboard
*/
public void onBack(View view) {
startActivity(new Intent(branch.this, dashboard.class));
}
}
and Heres my postman response for my php code:
[
{
"branchid": 12,
"username": "king",
"password": "202cb962ac59075b964b07152d234b70",
"branchname": "123branch",
"sys_id": 8,
"created": "2019-10-28 20:45:08",
"user_type": "Branch"
},
{
"branchid": 13,
"username": "makoy",
"password": "bda639c314e39023789c37d7a07469f9",
"branchname": "makoy",
"sys_id": 8,
"created": "2019-10-28 20:50:41",
"user_type": "Branch"
},
{
"branchid": 14,
"username": "foodbranch",
"password": "202cb962ac59075b964b07152d234b70",
"branchname": "foodbranch",
"sys_id": 8,
"created": "2019-10-28 22:01:59",
"user_type": "Branch"
},
{
"branchid": 15,
"username": "081nao397",
"password": "7815696ecbf1c96e6894b779456d330e",
"branchname": "testingbranchname",
"sys_id": 8,
"created": "2019-11-08 08:21:01",
"user_type": "Branch"
},
{
"branchid": 16,
"username": "testing101",
"password": "7815696ecbf1c96e6894b779456d330e",
"branchname": "rest",
"sys_id": 8,
"created": "2019-11-08 08:28:55",
"user_type": "Branch"
}
]
I think I am finally close to making this problem done since I managed to make the database part show a correct array (the result is the postman result that I posted above)
XML Codes
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".main.Functions.dash_branch.branch">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="#+id/btnBack"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_marginLeft="30sp"
android:layout_marginTop="30sp"
android:onClick="onBack"
android:padding="10sp"
android:text="Back"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.008"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0"></Button>
<Button
android:id="#+id/btnAdd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_marginTop="30sp"
android:layout_marginRight="30sp"
android:onClick="onAddBranch"
android:padding="10sp"
android:text="+"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.008"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0"></Button>
</RelativeLayout>
<RelativeLayout
android:id="#+id/layoutviewbranch"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<de.codecrafters.tableview.TableView
android:id="#+id/tableView"
android:layout_width="wrap_content"
android:layout_height="450sp"
app:tableView_columnCount="2">
</de.codecrafters.tableview.TableView>
</RelativeLayout>
<Button
android:layout_marginTop="20sp"
android:layout_gravity="center"
android:onClick="onTableshow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Show">
</Button>
</LinearLayout>
Logcat Error
FATAL EXCEPTION: main
Process: com.example.sample1myapp, PID: 25355
java.lang.IllegalStateException: Could not execute method for android:onClick
at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:402)
at android.view.View.performClick(View.java:7125)
at android.view.View.performClickInternal(View.java:7102)
at android.view.View.access$3500(View.java:801)
at android.view.View$PerformClick.run(View.java:27336)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
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.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:397)
at android.view.View.performClick(View.java:7125)
at android.view.View.performClickInternal(View.java:7102)
at android.view.View.access$3500(View.java:801)
at android.view.View$PerformClick.run(View.java:27336)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
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.NullPointerException: Attempt to invoke virtual method 'android.content.Context
android.content.Context.getApplicationContext()' on a null object
reference
at android.content.ContextWrapper.getApplicationContext(ContextWrapper.java:118)
at com.example.sample1myapp.System.RequestHandler.getRequestQueue(RequestHandler.java:30)
at com.example.sample1myapp.System.RequestHandler.<init>(RequestHandler.java:16)
at com.example.sample1myapp.System.RequestHandler.getInstance(RequestHandler.java:21)
at com.example.sample1myapp.main.Functions.dash_branch.bTSQLClient.retrieve(bTSQLClient.java:146)
at com.example.sample1myapp.main.Functions.dash_branch.branch.onTableshow(branch.java:78)
at java.lang.reflect.Method.invoke(Native Method)
at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:397)
at android.view.View.performClick(View.java:7125)
at android.view.View.performClickInternal(View.java:7102)
at android.view.View.access$3500(View.java:801)
at android.view.View$PerformClick.run(View.java:27336)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
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)
Related
I try to implement MVVM by Mindorks to show data from here :(https://api.themoviedb.org/3/movie/384018?api_key=67bc513a7a353631119fdffe5f7377a8&language=en-US) in my Activity. I try using databinding for update UI, but after the data is update, databinding not update my textview. here my Detail Activity Class :
public class DetailActivity extends BaseActivity<ActivityDetailBinding, DetailViewModel> implements DetailNavigator {
#Inject
DetailViewModel detailViewModel;
public static final String INTENT_ID = "id_intent";
public static final String INTENT_FLAG = "id_flag";
private ActivityDetailBinding mActivityDetailBinding;
public static Intent newIntent(Context context) {
return new Intent(context, DetailActivity.class);
}
#Override
public int getBindingVariable() {
return BR.viewModel;
}
#Override
public int getLayoutId() {
return R.layout.activity_detail;
}
#Override
public DetailViewModel getViewModel() {
return detailViewModel;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail);
detailViewModel.setNavigator(this);
mActivityDetailBinding = getViewDataBinding();
initView();
initData(savedInstanceState);
}
private void initData(Bundle savedInstanceState) {
Bundle extras = getIntent().getExtras();
if (extras != null) {
int id = extras.getInt(INTENT_ID, 0);
int flag = extras.getInt(INTENT_FLAG, 0);
detailViewModel.fetchDetail(id, flag);
}
}
private void initView() {
if (getSupportActionBar() != null) {
getSupportActionBar().hide();
}
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
#Override
public void ShowProgressDialog(Boolean loading) {
if (loading) {
showLoading();
} else {
hideLoading();
}
}
}
and my BaseActivity like this :
public abstract class BaseActivity<T extends ViewDataBinding, V extends BaseViewModel> extends AppCompatActivity
implements BaseFragment.Callback {
// TODO
// this can probably depend on isLoading variable of BaseViewModel,
// since its going to be common for all the activities
private ProgressDialog mProgressDialog;
private T mViewDataBinding;
private V mViewModel;
/**
* Override for set binding variable
*
* #return variable id
*/
public abstract int getBindingVariable();
/**
* #return layout resource id
*/
public abstract
#LayoutRes
int getLayoutId();
/**
* Override for set view model
*
* #return view model instance
*/
public abstract V getViewModel();
#Override
public void onFragmentAttached() {
}
#Override
public void onFragmentDetached(String tag) {
}
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
performDependencyInjection();
super.onCreate(savedInstanceState);
performDataBinding();
}
public T getViewDataBinding() {
return mViewDataBinding;
}
#TargetApi(Build.VERSION_CODES.M)
public boolean hasPermission(String permission) {
return Build.VERSION.SDK_INT < Build.VERSION_CODES.M ||
checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED;
}
public void hideKeyboard() {
View view = this.getCurrentFocus();
if (view != null) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm != null) {
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
}
}
public void hideLoading() {
if (mProgressDialog != null && mProgressDialog.isShowing()) {
mProgressDialog.cancel();
}
}
public void showLoading() {
hideLoading();
mProgressDialog = CommonUtils.showLoadingDialog(this);
}
public boolean isNetworkConnected() {
return NetworkUtils.isNetworkConnected(getApplicationContext());
}
public void performDependencyInjection() {
AndroidInjection.inject(this);
}
#TargetApi(Build.VERSION_CODES.M)
public void requestPermissionsSafely(String[] permissions, int requestCode) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(permissions, requestCode);
}
}
// public void showLoading() {
// hideLoading();
// mProgressDialog = CommonUtils.showLoadingDialog(this);
// }
private void performDataBinding() {
mViewDataBinding = DataBindingUtil.setContentView(this, getLayoutId());
this.mViewModel = mViewModel == null ? getViewModel() : mViewModel;
mViewDataBinding.setVariable(getBindingVariable(), mViewModel);
mViewDataBinding.setLifecycleOwner(this);
mViewDataBinding.executePendingBindings();
}
#Override
protected void onResume() {
super.onResume();
}
#Override
protected void onDestroy() {
super.onDestroy();
}
}
this is my ViewModel class :
public class DetailViewModel extends BaseViewModel<DetailNavigator> {
private final ObservableField<String> originalName = new ObservableField<>();
private final ObservableField<String> releaseDate = new ObservableField<>();
private final ObservableField<String> overview = new ObservableField<>();
private final ObservableField<String> genreMovie = new ObservableField<>();
private final ObservableField<String> posterPath = new ObservableField<>();
private final ObservableField<String> voteAverage = new ObservableField<>();
public DetailViewModel(DataManager dataManager, SchedulerProvider schedulerProvider) {
super(dataManager, schedulerProvider);
}
public void fetchDetail(int id, int flag) {
if (flag == 1) {
getNavigator().ShowProgressDialog(true);
getCompositeDisposable().add(getDataManager()
.getApiHelper().doDetailMovie(id, URLConfig.API_KEY, getDataManager().getLanguage())
.subscribeOn(getSchedulerProvider().io())
.observeOn(getSchedulerProvider().ui())
.subscribe(detailResponse -> {
setUpData(detailResponse);
getNavigator().ShowProgressDialog(false);
}, throwable -> {
getNavigator().ShowProgressDialog(false);
}));
} else if (flag == 2) {
getNavigator().ShowProgressDialog(true);
getCompositeDisposable().add(getDataManager()
.getApiHelper().doDetailTV(id, URLConfig.API_KEY, getDataManager().getLanguage())
.subscribeOn(getSchedulerProvider().io())
.observeOn(getSchedulerProvider().ui())
.subscribe(detailResponse -> {
setUpData(detailResponse);
getNavigator().ShowProgressDialog(false);
}, throwable -> {
getNavigator().ShowProgressDialog(false);
}));
}
}
private void setUpData(DetailResponse detailResponse) {
if (detailResponse.getOriginal_name() != null) {
originalName.set(detailResponse.getOriginal_name());
} else {
originalName.set(detailResponse.getOriginal_title());
}
originalName.notifyChange();
if (detailResponse.getFirst_air_date() != null) {
releaseDate.set(detailResponse.getFirst_air_date());
} else {
releaseDate.set(detailResponse.getRelease_date());
}
overview.set(String.valueOf(detailResponse.getOverview()));
posterPath.set(String.valueOf(detailResponse.getPoster_path()));
voteAverage.set(String.valueOf(detailResponse.getVote_average()));
String genres = "";
for (int i = 0;i<detailResponse.getGenreList().size();i++){
genres = genres+detailResponse.getGenreList().get(i);
}
genreMovie.set(genres);
}
public ObservableField<String> getOriginalName() {
return originalName;
}
public ObservableField<String> getReleaseDate() {
return releaseDate;
}
public ObservableField<String> getOverview() {
return overview;
}
public ObservableField<String> getGenreMovie() {
return genreMovie;
}
public ObservableField<String> getPosterPath() {
return posterPath;
}
public ObservableField<String> getVoteAverage() {
return voteAverage;
}
}
and this is my DetailResponse Class :
public class DetailResponse {
#SerializedName("original_name")
private String original_name ;
#SerializedName("original_title")
private String original_title ;
#SerializedName("release_date")
private String release_date ;
#SerializedName("first_air_date")
private String first_air_date ;
#SerializedName("vote_average")
private Double vote_average ;
#SerializedName("overview")
private String overview ;
#SerializedName("poster_path")
private String poster_path;
#SerializedName("genres")
private List<Genre> genreList;
public String getOriginal_name() {
return original_name;
}
public String getOriginal_title() {
return original_title;
}
public String getRelease_date() {
return release_date;
}
public String getFirst_air_date() {
return first_air_date;
}
public Double getVote_average() {
return vote_average;
}
public String getOverview() {
return overview;
}
public String getPoster_path() {
return poster_path;
}
public List<Genre> getGenreList() {
return genreList;
}
public static class Genre{
#SerializedName("name")
private String name ;
public String getName() {
return name;
}
}
}
and last one, here how I try to get data in my UI using databinding, this is my layout :
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".ui.detail.DetailActivity">
<data>
<variable
name="viewModel"
type="test.ui.detail.DetailViewModel" />
</data>
<androidx.core.widget.NestedScrollView
android:id="#+id/nestedScrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:animateLayoutChanges="true">
<com.github.florent37.shapeofview.shapes.ArcView
android:id="#+id/shape_header"
android:layout_width="match_parent"
android:layout_height="#dimen/size300dp"
android:alpha="0.7"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:shape_arc_cropDirection="outside"
app:shape_arc_height="#dimen/size30dp"
app:shape_arc_position="bottom">
<com.flaviofaria.kenburnsview.KenBurnsView
android:id="#+id/image_header"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="#drawable/poster_avengerinfinity"
android:tint="#6F000000" />
</com.github.florent37.shapeofview.shapes.ArcView>
<com.github.florent37.shapeofview.shapes.RoundRectView
android:id="#+id/shape_poster"
android:layout_width="#dimen/size150dp"
android:layout_height="#dimen/size200dp"
android:layout_marginTop="#dimen/margin250dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="#+id/shape_header"
app:shape_roundRect_bottomLeftRadius="#dimen/corner10dp"
app:shape_roundRect_bottomRightRadius="#dimen/corner10dp"
app:shape_roundRect_topLeftRadius="#dimen/corner10dp"
app:shape_roundRect_topRightRadius="#dimen/corner10dp">
<ImageView
android:id="#+id/image_poster"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="#string/hint_poster"
android:scaleType="fitXY"
app:imageDetailUrl="#{viewModel.posterPath}"
android:src="#drawable/poster_avengerinfinity" />
</com.github.florent37.shapeofview.shapes.RoundRectView>
<TextView
android:id="#+id/text_title"
style="#style/FontText.Title.Detail"
android:layout_marginTop="#dimen/margin15dp"
android:textSize="#dimen/font_large_size"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/shape_poster"
android:text="#{viewModel.originalName}"
tools:text="#string/hint_title" />
<TextView
android:id="#+id/text_title_release"
style="#style/FontText"
android:layout_marginTop="#dimen/margin10dp"
android:text="#string/text_release"
app:layout_constraintEnd_toStartOf="#+id/guideline"
app:layout_constraintTop_toBottomOf="#+id/text_title" />
<TextView
android:id="#+id/text_release"
style="#style/FontText"
android:layout_marginStart="#dimen/margin2dp"
android:layout_marginTop="#dimen/margin10dp"
app:layout_constraintStart_toEndOf="#+id/text_title_release"
app:layout_constraintTop_toBottomOf="#+id/text_title"
tools:text="#string/hint_release" />
<TextView
android:id="#+id/text_genres"
style="#style/FontText.Normal"
android:layout_marginStart="#dimen/margin15dp"
android:layout_marginTop="#dimen/margin10dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/text_release"
tools:text="#string/hint_genres" />
<TextView
android:id="#+id/text_duration"
style="#style/FontText.Normal.White"
android:layout_marginTop="#dimen/margin10dp"
android:layout_marginEnd="#dimen/margin15dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#+id/text_release"
tools:text="#string/hint_duration" />
<RatingBar
android:id="#+id/rating_bar"
android:layout_width="wrap_content"
android:layout_height="45dp"
android:layout_marginStart="#dimen/margin15dp"
android:layout_marginTop="#dimen/margin5dp"
android:isIndicator="true"
android:numStars="5"
android:rating="3.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/text_duration" />
<TextView
android:id="#+id/text_rating"
style="#style/FontText.Rating.Orange"
android:layout_marginStart="#dimen/margin5dp"
app:layout_constraintRight_toLeftOf="parent"
app:layout_constraintStart_toEndOf="#+id/rating_bar"
app:layout_constraintTop_toBottomOf="#+id/text_duration"
tools:text="#string/hit_rating" />
<TextView
android:id="#+id/text_default_rating"
style="#style/FontText.Rating"
android:textStyle="normal"
app:layout_constraintRight_toLeftOf="parent"
app:layout_constraintStart_toEndOf="#+id/text_rating"
app:layout_constraintTop_toBottomOf="#+id/text_duration"
tools:text="#string/hint_default_rating" />
<TextView
android:id="#+id/text_desc"
style="#style/FontText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="#dimen/margin15dp"
android:layout_marginTop="#dimen/margin25dp"
android:layout_marginEnd="#dimen/margin15dp"
android:paddingBottom="#dimen/padding100dp"
app:layout_constraintTop_toBottomOf="#+id/rating_bar"
tools:text="#string/hint_desc" />
<androidx.constraintlayout.widget.Guideline
android:id="#+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.5" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
</layout>
I try to show one data first, that is OriginalName for text_title, went I debug my application
public ObservableField<String> getOriginalName() {
return originalName;
}
getOriginalName in class ViewModel, just called before I retrieve my response, but after OriginalName is set, the UI not update and getOriginalName is never called again.I already add originalName.notifyChange(); after the data is set, but it doesn't seem change anything.
I already frustased.. so please... I hope anybody can help me to show me what to do. Thank you very much.
Remove this below line from Detail Activity
setContentView(R.layout.activity_detail);
In your base activity you have performDataBinding method which set the layout id using DataBindingUtil class.
mViewDataBinding = DataBindingUtil.setContentView(this, getLayoutId());
this.mViewModel = mViewModel == null ? getViewModel() : mViewModel;
mViewDataBinding.setVariable(getBindingVariable(), mViewModel);
mViewDataBinding.setLifecycleOwner(this);
mViewDataBinding.executePendingBindings();
I want to retrieve all child of my firebase database with for loop and data will be shown in recyclerview in a fragment. When I go event fragment, app crash and the error point out to the line of for looping
here is my code,
events.java(this is fragment)
FirebaseDatabase.getInstance().getReference().child("Users/" + mUser.getUid() + "/Groups/RequestedGroups").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot ds : dataSnapshot.getChildren()){
value = ds.child("GroupID").getValue().toString();
groupId.add(value);
}
retrieveGroups(groupId);
}
private void retrieveGroups(ArrayList<String> groupId) {
if(groupId != null){
for(String value : groupId){
FirebaseDatabase.getInstance().getReference().child("Events/"+value).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for(DataSnapshot d : dataSnapshot.getChildren()){
Event_Retrieve e = d.getValue(Event_Retrieve.class); // error point out this line
list.add(e);
}
adapter = new MyAdapter(events.this.getActivity(),list);
recyclerView.setAdapter(adapter);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(events.this.getActivity(), "oops", Toast.LENGTH_SHORT).show();
}
});
}
}
}
Event_Retrieve.java
public class Event_Retrieve {
public String eventname;
public String eventdescription;
public String eventdate;
public String eventtime;
public String eventphotourl;
public String latitude;
public String lingitude;
public ArrayList<String> acceptedmember;
public ArrayList<String> invitedmember;
public Event_Retrieve(){
}
public Event_Retrieve(String eventname, String eventdescription, String eventdate, String eventtime, String eventphotourl, String latitude, String lingitude, ArrayList<String> acceptedmember, ArrayList<String> invitedmember) {
this.eventname = eventname;
this.eventdescription = eventdescription;
this.eventdate = eventdate;
this.eventtime = eventtime;
this.eventphotourl = eventphotourl;
this.latitude = latitude;
this.lingitude = lingitude;
this.acceptedmember = acceptedmember;
this.invitedmember = invitedmember;
}
public String getEventname() {
return eventname;
}
public String getEventdescription() {
return eventdescription;
}
public String getEventdate() {
return eventdate;
}
public String getEventtime() {
return eventtime;
}
public String getEventphotourl() {
return eventphotourl;
}
public String getLatitude() {
return latitude;
}
public String getLingitude() {
return lingitude;
}
public ArrayList<String> getAcceptedmember() {
return acceptedmember;
}
public ArrayList<String> getInvitedmember() {
return invitedmember;
}
}
fragment_event.xml
<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"
android:background="#color/background"
tools:context=".places">
<!-- TODO: Update blank fragment layout -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="#+id/eventID"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp"
android:text="Events"
android:textColor="#000"
android:textSize="30sp" />
<android.support.v7.widget.RecyclerView
android:id="#+id/myRecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
Logcat error
E/HotwordDetector: Error at creating and/or starting hotword recognition.
java.lang.IllegalArgumentException: Invalid speaker model provided
at com.google.speech.micro.GoogleHotwordRecognizer.nativeNew(Native Method)
at com.google.speech.micro.GoogleHotwordRecognizer.<init>(SourceFile:6)
at com.google.android.libraries.assistant.hotword.k.a(SourceFile:66)
at com.google.android.libraries.assistant.hotword.k.at(SourceFile:35)
at com.google.android.apps.gsa.voiceinteraction.hotword.a.dGU(SourceFile:48)
at com.google.android.voiceinteraction.GsaVoiceInteractionService.dGU(SourceFile:109)
at com.google.android.voiceinteraction.g.oa(SourceFile:13)
at com.google.android.libraries.assistant.hotword.f.a(SourceFile:30)
at com.google.android.libraries.assistant.hotword.g.run(Unknown Source)
at com.google.android.libraries.gsa.runner.a.b.run(Unknown Source)
at com.google.android.apps.gsa.shared.util.concurrent.b.cq.bsW(SourceFile:2)
at com.google.android.apps.gsa.shared.util.concurrent.b.cp.run(SourceFile:5)
at com.google.android.apps.gsa.shared.util.concurrent.b.i.run(Unknown Source)
at com.google.android.apps.gsa.shared.util.concurrent.b.bs.run(SourceFile:3)
at com.google.android.apps.gsa.shared.util.concurrent.b.bs.run(SourceFile:3)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:760)
at com.google.android.apps.gsa.shared.util.concurrent.b.o.run(SourceFile:6)
My Database Structure
this is test data
I'm a newbie in the Android development an am trying to parse complex JSON structure with the help of rertofit library from the http://api.tvmaze.com/search/shows?q=girls. But my project fails in loading data. I suppose that the problem is in the GSON model, but I'm in complete bewilderment what's exactly wrong.
I need to fetch only image and title
I have already included the internet permission in the manifest
response looks like that:
[
{
"score": 17.314238,
"show": {
"id": 139,
"url": "http://www.tvmaze.com/shows/139/girls",
"name": "Girls",
"type": "Scripted",
"language": "English",
"genres": [
"Drama",
"Romance"
],
"status": "Ended",
"runtime": 30,
"premiered": "2012-04-15",
"officialSite": "http://www.hbo.com/girls",
"schedule": {
"time": "22:00",
"days": [
"Sunday"
]
},
"rating": {
"average": 6.7
},
"weight": 94,
"network": {
"id": 8,
"name": "HBO",
"country": {
"name": "United States",
"code": "US",
"timezone": "America/New_York"
}
},
"webChannel": null,
"externals": {
"tvrage": 30124,
"thetvdb": 220411,
"imdb": "tt1723816"
},
"image": {
"medium": "http://static.tvmaze.com/uploads/images/medium_portrait/31/78286.jpg",
"original": "http://static.tvmaze.com/uploads/images/original_untouched/31/78286.jpg"
},
"summary": "<p>This Emmy winning series is a comic look at the assorted humiliations and rare triumphs of a group of girls in their 20s.</p>",
"updated": 1538265422,
"_links": {
"self": {
"href": "http://api.tvmaze.com/shows/139"
},
"previousepisode": {
"href": "http://api.tvmaze.com/episodes/1079686"
}
}
}
},
{
"score": 13.229476,
"show": {
"id": 23542,
"url": "http://www.tvmaze.com/shows/23542/good-girls",
"name": "Good Girls",
"type": "Scripted",
"language": "English",
"genres": [
"Drama",
"Comedy",
"Crime"
],
"status": "Running",
"runtime": 60,
"premiered": "2018-02-26",
"officialSite": "https://www.nbc.com/good-girls?nbc=1",
"schedule": {
"time": "22:00",
"days": [
"Monday"
]
},
"rating": {
"average": 7
},
"weight": 92,
"network": {
"id": 1,
"name": "NBC",
"country": {
"name": "United States",
"code": "US",
"timezone": "America/New_York"
}
},
"webChannel": null,
"externals": {
"tvrage": null,
"thetvdb": 328577,
"imdb": "tt6474378"
},
"image": {
"medium": "http://static.tvmaze.com/uploads/images/medium_portrait/141/354343.jpg",
"original": "http://static.tvmaze.com/uploads/images/original_untouched/141/354343.jpg"
},
"summary": "<p><b>Good Girls</b> follows three \"good girl\" suburban wives and mothers who suddenly find themselves in desperate circumstances and decide to stop playing it safe, and risk everything to take their power back.</p>",
"updated": 1532345475,
"_links": {
"self": {
"href": "http://api.tvmaze.com/shows/23542"
},
"previousepisode": {
"href": "http://api.tvmaze.com/episodes/1425058"
}
}
}
},
......
]
I build my model class for fetching image and title, because i need only htese two items:
public class Image:
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Image {
#SerializedName("medium")
#Expose
private String medium;
#SerializedName("original")
#Expose
private String original;
public String getMedium() {
return medium;
}
public void setMedium(String medium) {
this.medium = medium;
}
public String getOriginal() {
return original;
}
public void setOriginal(String original) {
this.original = original;
}
}
public class Movie:
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Movie {
#SerializedName("name")
#Expose
private String name;
#SerializedName("image")
#Expose
private Image image;
public String getTitle() {
return name;
}
public void setTitle(String name) {
this.name = name;
}
public Image getImageUrl() {
return image;
}
public void setImageUrl(Image image) {
this.image = image;
}
}
A recyclerview adapter for those items:
public class MovieAdapter extends RecyclerView.Adapter<MovieAdapter.MyViewHolder> implements Filterable {
private List<Movie> movieList;
private List<Movie> movieListFiltered;
private Context context;
public void setMovieList(Context context,final List<Movie> movieList){
this.context = context;
this.movieList = movieList;
this.movieListFiltered = movieList;
}
#Override
public MovieAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item,parent,false);
return new MyViewHolder(view);
}
#Override
public void onBindViewHolder(MovieAdapter.MyViewHolder holder, int position) {
holder.title.setText(movieListFiltered.get(position).getTitle());
GlideApp.with(context).load(movieList.get(position).getImageUrl()).listener(new RequestListener() {
#Override
public boolean onLoadFailed(#Nullable GlideException e, Object model, Target target, boolean isFirstResource) {
// Log the GlideException here (locally or with a remote logging framework):
Log.e(TAG, "Load failed", e);
// You can also log the individual causes:
for (Throwable t : e.getRootCauses()) {
Log.e(TAG, "Caused by", t);
}
// Or, to log all root causes locally, you can use the built in helper method:
e.logRootCauses(TAG);
return false; // Allow calling onLoadFailed on the Target.
}
#Override
public boolean onResourceReady(Object resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) {
// Log successes here or use DataSource to keep track of cache hits and misses.
return false; // Allow calling onResourceReady on the Target.
}
}).into(holder.image);
}
#Override
public int getItemCount() {
if(movieList != null&& movieListFiltered!=null){
return movieListFiltered.size();
} else {
return 0;
}
}
#Override
public Filter getFilter() {
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence charSequence) {
String charString = charSequence.toString();
if (charString.isEmpty()) {
movieListFiltered = movieList;
} else {
List<Movie> filteredList = new ArrayList<>();
for (Movie movie : movieList) {
if (movie.getTitle().toLowerCase().contains(charString.toLowerCase())) {
filteredList.add(movie);
}
}
movieListFiltered = filteredList;
}
FilterResults filterResults = new FilterResults();
filterResults.values = movieListFiltered;
return filterResults;
}
#Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
movieListFiltered = (ArrayList<Movie>) filterResults.values;
notifyDataSetChanged();
}
};
}
public class MyViewHolder extends RecyclerView.ViewHolder {
TextView title;
ImageView image;
public MyViewHolder(View view) {
super(view);
title = (TextView) view.findViewById(R.id.title);
image = (ImageView)view.findViewById(R.id.image);
}
}
}
My MainActivity:
public class MainActivity extends AppCompatActivity {
private SearchView searchView;
private RecyclerView recyclerView;
private MovieAdapter movieAdapter;
private List<Movie> movieList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
movieList = new ArrayList<>();
recyclerView = (RecyclerView) findViewById(R.id.recyclerview);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
movieAdapter = new MovieAdapter();
recyclerView.setAdapter(movieAdapter);
ApiInterface apiService = TvMazeApiClient.getClient().create(ApiInterface.class);
Call<List<Movie>> call = apiService.getMovies();
call.enqueue(new Callback<List<Movie>>() {
#Override
public void onResponse(Call<List<Movie>> call, Response<List<Movie>> response) {
if(movieList != null) {
movieList = response.body();
Log.d("TAG", "Response = " + movieList);
movieAdapter.setMovieList(getApplicationContext(), movieList);
}
else{
Toast.makeText(MainActivity.this,"error", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(Call<List<Movie>> call, Throwable t) {
Log.d("TAG","Response = "+t.toString());
Toast.makeText(MainActivity.this,t.getLocalizedMessage(), Toast.LENGTH_SHORT).show();
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.options_menu, menu);
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
searchView = (SearchView) menu.findItem(R.id.action_search)
.getActionView();
searchView.setSearchableInfo(searchManager
.getSearchableInfo(getComponentName()));
searchView.setMaxWidth(Integer.MAX_VALUE);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
movieAdapter.getFilter().filter(query);
return false;
}
#Override
public boolean onQueryTextChange(String query) {
movieAdapter.getFilter().filter(query);
return false;
}
});
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_search) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onBackPressed() {
if (!searchView.isIconified()) {
searchView.setIconified(true);
return;
}
super.onBackPressed();
}}
my xml file for item:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="wrap_content"
>
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="160dp"
android:orientation="horizontal"
android:padding="8dp">
<ImageView
android:id="#+id/image"
android:layout_width="100dp"
android:layout_height="match_parent"
android:layout_marginRight="8dp"
android:scaleType="fitXY" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Title"
android:textSize="16sp"
android:textStyle="bold"
/>
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
Interface:
public interface ApiInterface {
#GET("search/shows?q=girls")
Call <List<Movie>> getMovies();
}
Client:
public class TvMazeApiClient {
public static String BASE_URL ="http://api.tvmaze.com/";
private static Retrofit retrofit;
public static Retrofit getClient(){
if(retrofit == null){
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
Thanks in advance for any help
The fields "name" and "image" that you are trying to parse are nested in a JSON object "show". You need to parse this field as well.
public interface ApiInterface {
#GET("search/shows?q=girls")
Call <List<MovieResponse>> getMovies();
}
Create a new Java object
public class MovieResponse {
#SerializedName("show")
#Expose
private Movie show;
public Movie getShow() {
return show;
}
}
I am having a problem with cardview not displaying some from the database.
My app connects to a grails back end which has a PostgreSQL db.
I have a cardview inside a recyclerview. It receives 7 values in form of JSON but on running the app, only 5 are displayed. I try doing System.out of the JSON in the stack trace and I find that all the 7 values are received so everything is okay on that front.
For clarity purposes, the fields that are not being displayed are labs("labs") and drugs administered("drugsAdministered").
Here is the main class(ClinicalHistory.java), the adapter class, the xml and the stack-trace.
ClinicalHistory.java
public class ClinicalHistory extends AppCompatActivity {
RecyclerView clinicalHistory_rv;
SwipeRefreshLayout swipeRefreshLayout;
List<com.example.user.eafya.models.ClinicalHistory> clinicalHistory_List;
com.example.user.eafya.models.ClinicalHistory clinicalHistory;
ClinicalHistoryAdapter clinicalHistoryAdapter;
private StringRequest clinicalHistoryRequest;
private LinearLayout no_data;
private LinearLayoutManager linearLayoutManager;
private RequestQueue requestQueue;
private ProgressDialog pb;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_clinical_history);
initWidgets();
fetchData();
}
private void fetchData() {
pb = new ProgressDialog(this);
pb.setIcon(R.mipmap.ic_launcher);
pb.setTitle("Please wait");
pb.setCancelable(false);
pb.setMessage("Loading data..");
pb.show();
clinicalHistoryRequest = new StringRequest(Request.Method.GET, Configs.URL_LOGIN + Configs.CLINICALHISTORY_PATH, new Response.Listener<String>() {
#Override
public void onResponse(String result) {
pb.dismiss();
System.out.print("======================================"+ result);
try {
JSONObject jsonObject = new JSONObject(result);
JSONArray jsonArray = jsonObject.getJSONArray("mVisit");
for (int i=0;i<jsonArray.length();i++){
System.out.print("----------------"+jsonArray.getJSONObject(i).getString("labs"));
}
Log.d("myError: ", String.valueOf(jsonArray.length()));
if(jsonArray.length()<1) {
clinicalHistory_List.clear();
no_data.setVisibility(View.VISIBLE);
}else if( jsonArray.length()>0){
if(no_data.getVisibility()==View.VISIBLE){
no_data.setVisibility(View.GONE);
}
for(int i=0 ; i<jsonArray.length() ; i++){
JSONObject data = jsonArray.getJSONObject(i);
clinicalHistory = new com.example.user.eafya.models.ClinicalHistory();
clinicalHistory.setDate(data.getString("dateCreated"));
clinicalHistory.setHospital(data.getString("hospitalAttended"));
clinicalHistory.setDoctor(data.getString("attendingDoctor"));
clinicalHistory.setLabs(data.getString("labs"));
clinicalHistory.setChiefComplains(data.getString("chiefComplains"));
clinicalHistory.setDrugs(data.getString("drugsAdministered"));
clinicalHistory_List.add(clinicalHistory);
}
clinicalHistoryAdapter = new ClinicalHistoryAdapter(ClinicalHistory.this, clinicalHistory_List);
linearLayoutManager = new LinearLayoutManager(ClinicalHistory.this);
clinicalHistory_rv.setLayoutManager(linearLayoutManager);
clinicalHistory_rv.setItemAnimator(new DefaultItemAnimator());
clinicalHistory_rv.setAdapter(clinicalHistoryAdapter);
clinicalHistory_rv.setSaveEnabled(true);
clinicalHistory_rv.setSaveFromParentEnabled(true);
clinicalHistoryAdapter.notifyDataSetChanged();
}
} catch (JSONException e) {
Log.d("MaeraJ",e.toString());
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
pb.dismiss();
AlertDialog.Builder dialog = new AlertDialog.Builder(ClinicalHistory.this);
dialog.setTitle("Something went wrong !!");
dialog.setCancelable(true);
dialog.setIcon(R.mipmap.ic_launcher);
dialog.setMessage("Check your data connection");
dialog.setPositiveButton("RETRY", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
//retry
dialogInterface.dismiss();
fetchData();
}
});
dialog.setNegativeButton("CANCEL", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
//cancel
dialogInterface.dismiss();
}
});
dialog.create();
dialog.show();
Log.d("Maera",volleyError.toString());
}
});
requestQueue.add(clinicalHistoryRequest);
}
private void initWidgets() {
requestQueue = Volley.newRequestQueue(this);
no_data = findViewById(R.id.nodata_LY);
clinicalHistory_rv = findViewById(R.id.clinicalHistory_RV);
clinicalHistory_List = new ArrayList<>();
swipeRefreshLayout = findViewById(R.id.swipeContainer);
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
refresh();
}
});
}
private void refresh() {
try {
clinicalHistory_List.clear();
fetchData();
swipeRefreshLayout.setRefreshing(false);
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()){
case R.id.home:
onBackPressed();
break;
}
return super.onOptionsItemSelected(item);
}
}
Adapter class(ClinicalHistoryAdapter.java)
public class ClinicalHistoryAdapter extends RecyclerView.Adapter<ClinicalHistoryAdapter.myViewHolder> {
Context ctx;
List<ClinicalHistory> clinicalHistoryList;
ClinicalHistory clinicalHistoryModel;
LayoutInflater inflater;
public ClinicalHistoryAdapter(Context ctx, List<ClinicalHistory> clinicalHistoryList) {
this.ctx = ctx;
this.clinicalHistoryList = clinicalHistoryList;
inflater = LayoutInflater.from(ctx);
}
public class myViewHolder extends RecyclerView.ViewHolder {
TextView clinicalHist_date_TV,clinicalHist_hospital, clinicalHist_doctor,clinicalHist_chiefComplains, clinicalHist_labs, clinicalHist_drugs;
ImageView clinicalHist_img;
public myViewHolder(View itemView) {
super(itemView);
clinicalHist_img = itemView.findViewById(R.id.clinicalHist_image_IV);
clinicalHist_date_TV = itemView.findViewById(R.id.clinicalHist_date__TV);
clinicalHist_hospital = itemView.findViewById(R.id.clinicalHist_hospital_TV);
clinicalHist_doctor = itemView.findViewById(R.id.clinicalHist_doctor);
clinicalHist_chiefComplains = itemView.findViewById(R.id.clinicalHist_chief_complains_TV);
clinicalHist_labs = itemView.findViewById(R.id.clinicalHist_labs_TV);
clinicalHist_drugs = itemView.findViewById(R.id.clinicalHist_drugs_TV);
}
}
#Override
public ClinicalHistoryAdapter.myViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View my_view = inflater.inflate(R.layout.clinical_history_item,viewGroup,false);
return new myViewHolder(my_view);
}
#Override
public void onBindViewHolder(ClinicalHistoryAdapter.myViewHolder myViewHolder, final int position) {
clinicalHistoryModel = new ClinicalHistory();
clinicalHistoryModel = clinicalHistoryList.get(position);
myViewHolder.clinicalHist_date_TV.setText(clinicalHistoryModel.getDate());
myViewHolder.clinicalHist_hospital.setText(clinicalHistoryModel.getHospital());
myViewHolder.clinicalHist_doctor.setText(clinicalHistoryModel.getDoctor());
myViewHolder.clinicalHist_chiefComplains.setText(clinicalHistoryModel.getChiefComplains());
myViewHolder.clinicalHist_labs.setText(clinicalHistoryModel.getLabs());
myViewHolder.clinicalHist_drugs.setText(clinicalHistoryModel.getDrugs());
myViewHolder.clinicalHist_doctor.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
goToDetails(position);
}
});
myViewHolder.clinicalHist_hospital.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
goToDetails(position);
}
});
Glide.with(ctx).load(clinicalHistoryModel.getImg()).placeholder(R.drawable.loader).error(R.drawable.header).into(myViewHolder.clinicalHist_img);
}
private void goToDetails(int pos) {
clinicalHistoryModel = clinicalHistoryList.get(pos);
Intent intent = new Intent(ctx,MedicalDetailActivity.class);
intent.putExtra("dateCreated", clinicalHistoryModel.getDate());
intent.putExtra("clinicalHist_img", clinicalHistoryModel.getImg());
intent.putExtra("hospitalAttended", clinicalHistoryModel.getHospital());
intent.putExtra("attendingDoctor", clinicalHistoryModel.getDoctor());
intent.putExtra("chiefComplaints", clinicalHistoryModel.getChiefComplains());
intent.putExtra("labs", clinicalHistoryModel.getLabs());
intent.putExtra("drugs", clinicalHistoryModel.getLabs());
ctx.startActivity(intent);
}
#Override
public int getItemCount() {
return clinicalHistoryList.size();
}
}
The xml file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="4dp">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_margin="2dp"
android:orientation="horizontal"
android:padding="2dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/clinicalHist_image_IV"
android:layout_width="110dp"
android:layout_height="80dp"
android:layout_gravity="top"
android:scaleType="fitXY"
android:src="#drawable/header" />
<LinearLayout
android:padding="4dp"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:textAlignment="textStart"
android:layout_gravity="start"
android:id="#+id/clinicalHist_date__TV"
android:text="21/09/2012"
android:textColor="#color/colorAccent"
android:textAppearance="#android:style/TextAppearance.DeviceDefault.Medium"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:textAlignment="textStart"
android:layout_gravity="start"
android:id="#+id/clinicalHist_hospital_TV"
android:text="Hema Hospital"
android:textColor="#color/colorAccent"
android:textAppearance="#android:style/TextAppearance.DeviceDefault.Medium"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:id="#+id/clinicalHist_doctor"
android:text="Dr.Lilian"/>
<TextView
android:layout_gravity="center"
android:id="#+id/clinicalHist_labs_TV"
android:text=" Brucella "
android:textColor="#000"
android:textAppearance="#android:style/TextAppearance.DeviceDefault.Medium"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TextView
android:layout_gravity="center"
android:id="#+id/clinicalHist_chief_complains_TV"
android:text=" Headache "
android:textColor="#000"
android:textAppearance="#android:style/TextAppearance.DeviceDefault.Medium"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TextView
android:layout_gravity="center"
android:id="#+id/clinicalHist_drugs_TV"
android:text=" Brufen "
android:textColor="#000"
android:textAppearance="#android:style/TextAppearance.DeviceDefault.Medium"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
The stack trace
I/System.out: ======================================{"mVisit":[{"id":1,"chiefComplains":"Headache","dateCreated":"2017-08-11T21:00:00Z","labs":"Brucella","hospitalAttended":"Hema Hospital","drugsAdministered":"Tramadol","attendingDoctor":"Dr. Kisinga"
I have found the solution. The problem was in the model.
This was my previous model. Note the parameters in the
setDrugs() and setLabs().
public class ClinicalHistory {
String img;
String date;
String labs;
String hospital;
String chiefComplains;
String doctor;
String drugs;
public ClinicalHistory() {
}
public String getImg() {
return img;
}
public void setImg(String img) {
this.img = img;
}
public String getHospital() {
return this.hospital = hospital ;
}
public void setHospital(String hospital) {
this.hospital = hospital;
}
public String getChiefComplains(){return this.chiefComplains = chiefComplains;}
public void setChiefComplains(String chiefComplains){ this.chiefComplains = chiefComplains;}
public String getLabs() {
return this.labs = labs ;
}
public void setLabs(String hospital) {
this.labs = labs;
}
public String getDoctor() {
return this.doctor = doctor ;
}
public void setDoctor(String doctor) {
this.doctor = doctor;
}
public void setDrugs(String hospital) {
this.drugs = drugs;
}
public String getDrugs() {
return this.drugs = drugs ;
}
public void setDate(String date) {
this.date = date;
}
public String getDate() {
return date;
}
}
After I made this change it worked
public class ClinicalHistory {
String img;
String date;
String labs;
String hospital;
String chiefComplains;
String doctor;
String drugs;
public ClinicalHistory() {
}
public String getImg() {
return img;
}
public void setImg(String img) {
this.img = img;
}
public String getHospital() {
return this.hospital = hospital ;
}
public void setHospital(String hospital) {
this.hospital = hospital;
}
public String getChiefComplains(){return this.chiefComplains = chiefComplains;}
public void setChiefComplains(String chiefComplains){ this.chiefComplains = chiefComplains;}
public String getLabs() {
return this.labs = labs ;
}
public void setLabs(String labs) {
this.labs = labs;
}
public String getDoctor() {
return this.doctor = doctor ;
}
public void setDoctor(String doctor) {
this.doctor = doctor;
}
public void setDrugs(String drugs) {
this.drugs = drugs;
}
public String getDrugs() {
return this.drugs = drugs ;
}
public void setDate(String date) {
this.date = date;
}
public String getDate() {
return date;
}
}
This question already has answers here:
Why does Gson fromJson throw a JsonSyntaxException: Expected BEGIN_OBJECT but was BEGIN_ARRAY?
(2 answers)
Closed 5 years ago.
Can you help me to solving this error? Where is the problem?
private final String TAG = "MulaiUjian";
private RecyclerView recyclerView;
private LinearLayoutManager layoutManager;
private RecycleViewAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mulai_ujian);
recyclerView = (RecyclerView)findViewById(R.id.recycle_txtSoal);
layoutManager = new LinearLayoutManager(MulaiUjian.this);
recyclerView.setLayoutManager(layoutManager);
requestJsonObject();
Toolbar toolbar = (Toolbar)findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
if(getSupportActionBar()!=null){
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
}
}
private void requestJsonObject(){
RequestQueue queue = Volley.newRequestQueue(this);
String url ="https://www.rootorial.com/worthit2/resgister/showalluser.php";
StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d(TAG, "Response " + response);
GsonBuilder builder = new GsonBuilder();
Gson mGson = builder.create();
List<ItemObject> posts = new ArrayList<ItemObject>();
posts = Arrays.asList(mGson.fromJson(response, ItemObject[].class));
adapter = new RecycleViewAdapter(MulaiUjian.this, posts);
recyclerView.setAdapter(adapter);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d(TAG, "Error " + error.getMessage());
}
});
queue.add(stringRequest);
}
Stacktrace:
Process: com.example.root.pmb, PID: 7806
**com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was
BEGIN_OBJECT at line 1 column 2 path $**
at com.google.gson.Gson.fromJson(Gson.java:826)
at com.google.gson.Gson.fromJson(Gson.java:779)
at com.google.gson.Gson.fromJson(Gson.java:728)
at com.google.gson.Gson.fromJson(Gson.java:700)
at com.example.root.pmb.MulaiUjian$1.onResponse(MulaiUjian.java:59)
at com.example.root.pmb.MulaiUjian$1.onResponse(MulaiUjian.java:52)
at
com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:60)
at
com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:30)
at
com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:99)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5268)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:902)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:697)
Caused by: java.lang.IllegalStateException: Expected BEGIN_ARRAY but
was BEGIN_OBJECT at line 1 column 2 path $
at com.google.gson.stream.JsonReader.beginArray(JsonReader.java:350)
at
com.google.gson.internal.bind.ArrayTypeAdapter.read(ArrayTypeAdapter.java:70)
at com.google.gson.Gson.fromJson(Gson.java:814)
at com.google.gson.Gson.fromJson(Gson.java:779)
at com.google.gson.Gson.fromJson(Gson.java:728)
at com.google.gson.Gson.fromJson(Gson.java:700)
at com.example.root.pmb.MulaiUjian$1.onResponse(MulaiUjian.java:59)
at com.example.root.pmb.MulaiUjian$1.onResponse(MulaiUjian.java:52)
at
com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:60)
at
com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:30)
at
com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:99)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5268)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:902)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:697)
The problem is that, your whole JSON response is a JSONObject if see it carefully.
{
"id_soal": [{
"id_soal": "So0045",
"isi_soal": "Pemilihan Umum tahun 1999 diikuti oleh:",
"bobot_nilai": "1",
"jawab_a": "10 partai politik",
"jawab_b": "18 partai politik",
"jawab_c": "45 partai politik",
"jawab_d": "48 partai politik",
"jawaban_benar": "D"
}, {
"id_soal": "So0039",
"isi_soal": "Prinsup Pembangunan Berkelanjutan adalah :",
"bobot_nilai": "1",
"jawab_a": "Pembangunan terus menerus",
"jawab_b": "Pembangunan yang tidak merusak lingkungan",
"jawab_c": "Pembangunan yang mempertimbangkan kehidupan generasiyang akan datang",
"jawab_d": "Pembangunan yang sesuai rencana pemerintah",
"jawaban_benar": "C"
}, {
"id_soal": "So0065",
"isi_soal": "Dimanakah tempat dibacakan naskah Proklamasi Indonesia ?",
"bobot_nilai": "1",
"jawab_a": "Jl. Diponogoro No. 56",
"jawab_b": "Jl. Pegangsaan timur No. 56",
"jawab_c": "Jl. Teuku Umar No. 67",
"jawab_d": "Jl. Cokroaminoto No. 67",
"jawaban_benar": "B"
}
}
and for Gson to parse your Response Successfully you need to need to Have two model class like below
public class ItemObject {
private List<IdSoal> id_soal = null;
private Integer success;
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
public List<IdSoal> getIdSoal() {
return id_soal;
}
public void setIdSoal(List<IdSoal> idSoal) {
this.id_soal = idSoal;
}
public Integer getSuccess() {
return success;
}
public void setSuccess(Integer success) {
this.success = success;
}
}
and,
public class IdSoal {
private String id_soal;
private String isi_soal;
private String bobot_nilai;
private String jawab_a;
private String jawab_b;
private String jawab_c;
private String jawab_d;
private String jawaban_benar;
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
public String getId_soal() {
return id_soal;
}
public void setId_soal(String id_soal) {
this.id_soal = id_soal;
}
public String getIsi_soal() {
return isi_soal;
}
public void setIsi_soal(String isi_soal) {
this.isi_soal = isi_soal;
}
public String getBobot_nilai() {
return bobot_nilai;
}
public void setBobot_nilai(String bobot_nilai) {
this.bobot_nilai = bobot_nilai;
}
public String getJawab_a() {
return jawab_a;
}
public void setJawab_a(String jawab_a) {
this.jawab_a = jawab_a;
}
public String getJawab_b() {
return jawab_b;
}
public void setJawab_b(String jawab_b) {
this.jawab_b = jawab_b;
}
public String getJawab_c() {
return jawab_c;
}
public void setJawab_c(String jawab_c) {
this.jawab_c = jawab_c;
}
public String getJawab_d() {
return jawab_d;
}
public void setJawab_d(String jawab_d) {
this.jawab_d = jawab_d;
}
public String getJawaban_benar() {
return jawaban_benar;
}
public void setJawaban_benar(String jawaban_benar) {
this.jawaban_benar = jawaban_benar;
}
}
then all you need to do is like this
ItemObject itemObject = mGson.fromJson(response, ItemObject.class));
You probably need to check your models or the response you are receiving. You are using ItemObject[].class) but might be expecting an object so deserialization is failing.