How to create a full screen Android Wear app without cards - java

I'm brand new to Android programming and I'm trying to create a full screen Android Wear interface with custom layouts and no cards. I'm trying to go off the sample but I can't figure out how to get around using CardFragments. My MainActivity code is essentially identical to the example, with a few names changed. Here is the code for my GridViewPagerAdaper:
public class MyGridViewPagerAdapter extends FragmentGridPagerAdapter {
private final Context mContext;
public MyGridViewPagerAdapter(Context ctx, FragmentManager fm) {
super(fm);
mContext = ctx;
}
static final int[] BG_IMAGES = new int[]{
R.drawable.bg,
};
/**
* A simple container for static data in each page
*/
private static class Page {
int titleRes;
int textRes;
int iconRes;
int cardGravity = Gravity.BOTTOM;
boolean expansionEnabled = true;
float expansionFactor = 1.0f;
int expansionDirection = CardFragment.EXPAND_DOWN;
public Page(int titleRes) {
this.titleRes = titleRes;
this.textRes = textRes;
this.iconRes = iconRes;
}
public Page(int titleRes, int textRes, int iconRes, int gravity) {
this.titleRes = titleRes;
this.textRes = textRes;
this.iconRes = iconRes;
this.cardGravity = gravity;
}
}
private final Page[][] PAGES = {
{
new Page(R.drawable.tuner),
},
{
new Page(R.drawable.metronome),
new Page(R.drawable.metroplain)
},
};
#Override
public Fragment getFragment(int row, int col) {
Page page = PAGES[row][col];
// String title = page.titleRes != 0 ? mContext.getString(page.titleRes) : null;
// String text = page.textRes != 0 ? mContext.getString(page.textRes) : null;
CardFragment fragment = CardFragment.create("", "", page.iconRes);
// Advanced settings
fragment.setCardGravity(page.cardGravity);
fragment.setExpansionEnabled(page.expansionEnabled);
fragment.setExpansionDirection(page.expansionDirection);
fragment.setExpansionFactor(page.expansionFactor);
return fragment;
}
#Override
public ImageReference getBackground(int row, int column) {
return ImageReference.forDrawable(BG_IMAGES[row % BG_IMAGES.length]);
}
#Override
public int getRowCount() {
return PAGES.length;
}
#Override
public int getColumnCount(int rowNum) {
return PAGES[rowNum].length;
}
}
What's the best way to get rid of the cards and use a custom layout? Thanks for your help.

In your adapter, give your fragments as following:
private final Activity mContext;
private final Fragment[][] mFragment;
public MyGridViewPagerAdapter(Activity ctx, FragmentManager fm, Fragment[][] fragments)
{
super(fm);
mContext = ctx;
this.mFragment = fragments;
}
then override the following methods:
#Override
public Fragment getFragment(int row, int col)
{
return mFragment[row][col];
}
#Override
public int getRowCount()
{
return mFragment.length;
}
#Override
public int getColumnCount(int rowNum)
{
return mFragment[rowNum].length;
}
then in your activity do as following:
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
final GridViewPager pager = (GridViewPager) findViewById(R.id.pager);
final Fragment[][] items = {
{
CusmtomFragment.newInstance("your","arguments"),
CusmtomFragment.newInstance()
},
{
OtherFragment.newInstance(),
AnotherFragment.newInstance(1234)
}
};
// ....
pager.setAdapter(new MyGridViewPagerAdapter(this, getFragmentManager(), items));
}
Hope it helps !

If you implement a custom wearable app you can do what you want including a custom UI.
The problems are more to Is there any way to detect if the clock is round?
Or how to start the app you n the wearable. This is done with a special service. Basically you is the dataApi for that.

Related

How to open keyboard into service on Android [duplicate]

This question already has answers here:
Android - Keyboard not appearing in floating window
(4 answers)
How to display the Soft Keyboard from a Service?
(3 answers)
Closed 3 years ago.
In my application i should use Vertical Stepper and for this i added below library : VerticalStepperForm.
I should use this stepper into service and for this i write below codes.
But when use this codes into Service, when click on EditText not open soft keyboard (not show me any keyboard), but when use this codes into activity, it's not bug and show me keyboard.
But into service not show any keyboard!
My service codes:
public class FloatingLayoutService extends Service implements StepperFormListener {
private WindowManager windowManager;
private ConstraintLayout floatingLayout, floatingLay_root, floatingLay_main;
private IBinder binder = new ServiceBinder();
private LinearLayout floatingLay_headerLay;
private List<Step> steps = new ArrayList();
private List<Integer> intList = new ArrayList<>();
private List<TestStepsListResponse.Datum> testPlans = new ArrayList<>();
//Timer
private boolean running;
private int stepIndex = 1;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
//Inflate the layout using LayoutInflater
LayoutInflater li = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
floatingLayout = (ConstraintLayout) li.inflate(R.layout.service_floating_layout, null);
//Init view
initUi();
//Set layout params to display the controls over any screen.
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
// From API26, TYPE_PHONE deprecated. Use TYPE_APPLICATION_OVERLAY for O
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O)
params.type = WindowManager.LayoutParams.TYPE_PHONE;
//Initial position of the floating controls
params.gravity = Gravity.BOTTOM | Gravity.START;
params.x = 0;
params.y = 0;
//Add the controls view to windowManager
windowManager.addView(floatingLayout, params);
//Steps
testPlans = App.testPlansList;
for (int i = 0; i < testPlans.size(); i++) {
if (testPlans.get(i).getItemType().equals(ConstKeys.TEST_STEP_TEXT_RESPONSE)) {
StepDynamicEdt stepDynamicTxt = new StepDynamicEdt(testPlans.get(i).getTitle(), testPlans.get(i).getDesc());
// add to list
steps.add(stepDynamicTxt);
intList.add(i);
} else {
StepDynamicTxt stepDynamicEdt = new StepDynamicTxt(testPlans.get(i).getTitle(), testPlans.get(i).getDesc());
// add to list
steps.add(stepDynamicEdt);
}
}
floatingLay_stepper.setup(this, steps)
.allowNonLinearNavigation(false)
.displayCancelButtonInLastStep(false)
.displayBottomNavigation(false)
.confirmationStepTitle("OK")
.stepNextButtonText("Next")
.lastStepNextButtonText("Finish")
.includeConfirmationStep(false)
.init();
return START_STICKY;
}
StepDynamicEdt class codes:
public class StepDynamicEdt extends Step<String> {
private static final int MIN_CHARACTERS = 1;
private EditText editText;
private String errorMessage;
public StepDynamicEdt(String title) {
this(title, "");
}
public StepDynamicEdt(String title, String subtitle) {
super(title, subtitle);
}
#NonNull
#Override
protected View createStepContentLayout() {
//Create view programmatically
editText = new EditText(getContext());
editText.setHint("User name");
editText.setSingleLine(true);
editText.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
markAsCompletedOrUncompleted(true);
}
#Override
public void afterTextChanged(Editable s) {
}
});
editText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
getFormView().goToNextStep(true);
return false;
}
});
errorMessage = "Insert 1 character";
return editText;
}
#Override
public String getStepData() {
Editable text = editText.getText();
if (text != null) {
return text.toString();
}
return "";
}
#Override
public String getStepDataAsHumanReadableString() {
String name = getStepData();
return name == null || name.isEmpty() ? "Empty" : name;
}
#Override
public void restoreStepData(String data) {
if (editText != null) {
editText.setText(data);
}
}
#Override
protected IsDataValid isStepDataValid(String stepData) {
if (stepData.length() < MIN_CHARACTERS) {
return new IsDataValid(false, errorMessage);
} else {
return new IsDataValid(true);
}
}
#Override
protected void onStepOpened(boolean animated) {
// No need to do anything here
}
#Override
protected void onStepClosed(boolean animated) {
// No need to do anything here
}
#Override
protected void onStepMarkedAsCompleted(boolean animated) {
// No need to do anything here
}
#Override
protected void onStepMarkedAsUncompleted(boolean animated) {
// No need to do anything here
}
}
Update : I added below code into StepDynamicEdt class, but again not open keyboard!
InputMethodManager imm = (InputMethodManager) getContext().getSystemService(
Context.INPUT_METHOD_SERVICE);
Objects.requireNonNull(imm).showSoftInput(editText, 0);
How can i fix it and open keyboard into service ?

How to Delete Item Without Deleting Position in Recycler View?

I really need your help. I've searched Google many days with many keywords, but I couldn't get it. So, I decided to ask to you.
So, here it is. Actually, I have one button in RecyclerView, but this button is repeated as much amount of data available, there are: Button with text "Baca 3x", "Baca 4x", and so on. I want, if I click button with text "Baca 3x" 3 times, it will change to "Baca 2x" >> "Baca 1x" >> remove item. Also if I click button with text "Baca 4x" 4 times, it will change to "Baca 3x" >> "Baca 2x" >> "Baca 1x" >> remove item.
But my problem is, I can't treat every button with different treatment, because every time the item has been deleted, position of data changes automatically. Because of this, I can't get specific button. For example: There is two button,
1. Button "Baca 3x" on position 0
2. Button "Baca 4x" on position 1
If button "Baca 3x" on position 0 has been deleted, so button "Baca 4x" changed it's position automatically to 0. The problem lays here.
Until now I just get every button based on their positions, which is a problem for me. Because of this I am thinking about How to Delete Item Without Deleting Position in Recycler View? Can you guys solve my problem? Should I use DiffUtil?And how to use it? Below the complete code I use:
ModelDoa.java
public class ModelDoa {
public static final int DOA_PAGI = 0;
public static final int DOA_SORE = 1;
public static final int DOA_MASJID = 2;
public static final int DOA_BANGUNT = 3;
public static final int DOA_MAU_TIDUR = 4;
private String mName;
private String bName;
private int mType;
public ModelDoa(String name, String butong, int type) {
this.mName = name;
this.bName = butong;
this.mType = type;
}
public String getName() {
return mName;
}
public void setName(String name) {
this.mName = name;
}
public int getType() {
return mType;
}
public void setType(int type) { this.mType = type; }
public String ambilName() {
return bName;
}
public void setNama(String butonk) {
this.bName = butonk;
}
}
AdapterDoa.java
public class AdapterDoa extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
public List<ModelDoa> mList;
public AdapterDoa(List<ModelDoa> list) {
this.mList = list;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
switch (viewType) {
case DOA_PAGI:
View vieu = LayoutInflater.from(parent.getContext()).inflate(R.layout.content_doa, parent, false);
PagiViewHolder rcv = new PagiViewHolder(vieu, this);
return rcv;
case DOA_SORE:
View doa = LayoutInflater.from(parent.getContext()).inflate(R.layout.content_doa, parent, false);
SoreViewHolder mdoa = new SoreViewHolder(doa);
return mdoa;
case DOA_MASJID:
View dMasjid = LayoutInflater.from(parent.getContext()).inflate(R.layout.content_doa, parent, false);
MasjidViewHolder mMasjid = new MasjidViewHolder(dMasjid);
return mMasjid;
case DOA_BANGUNT:
View dBangunt = LayoutInflater.from(parent.getContext()).inflate(R.layout.content_doa, parent, false);
BanguntViewHolder mBangunt = new BanguntViewHolder(dBangunt);
return mBangunt;
case DOA_MAU_TIDUR:
View regut = LayoutInflater.from(parent.getContext()).inflate(R.layout.content_doa, parent, false);
MauTidurViewHolder turu = new MauTidurViewHolder(regut);
return turu;
}
return null;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
ModelDoa object = mList.get(position);
if (object != null) {
switch (object.getType()) {
case DOA_PAGI:
((PagiViewHolder) holder).mTitle.setText(object.getName());
((PagiViewHolder) holder).tombolbaca.setText(object.ambilName());
break;
case DOA_SORE:
((SoreViewHolder) holder).mTitle.setText(object.getName());
((SoreViewHolder) holder).tombolbaca.setText(object.ambilName());
break;
case DOA_MASJID:
((MasjidViewHolder) holder).mTitle.setText(object.getName());
((MasjidViewHolder) holder).tombolbaca.setText(object.ambilName());
break;
case DOA_BANGUNT:
((BanguntViewHolder) holder).mTitle.setText(object.getName());
((BanguntViewHolder) holder).tombolbaca.setText(object.ambilName());
break;
case DOA_MAU_TIDUR:
((MauTidurViewHolder) holder).mTitle.setText(object.getName());
((MauTidurViewHolder) holder).tombolbaca.setText(object.ambilName());
break;
}
}
}
public void deleteItem(int position) {
mList.remove(position); // hapus list
notifyItemRemoved(position); // hapus tampilan
// notifyItemRangeChanged( position, mList.size());
}
#Override
public int getItemCount() {
if (mList == null)
return 0;
return mList.size();
}
#Override
public int getItemViewType(int position) {
if (mList != null) {
ModelDoa object = mList.get(position);
if (object != null) {
return object.getType();
}
}
return 0;
}
}
PagiViewHolder.java
public class PagiViewHolder extends RecyclerView.ViewHolder {
public TextView mTitle;
public Button tombolbaca;
public Button teksbaca;
public Button tombolshare;
private RelativeLayout rl2;
private int klik10 = 10;
private AdapterDoa myAdapter;
public PagiViewHolder(View itemView, AdapterDoa myAdapter) {
super(itemView);
this.myAdapter = myAdapter;
itemView.setOnClickListener(mainViewClickListener);
mTitle = (TextView) itemView.findViewById(R.id.titleTextView);
tombolbaca = (Button) itemView.findViewById(R.id.buttonbaca);
tombolshare = (Button) itemView.findViewById(R.id.buttonshare);
tombolbaca.setOnClickListener(bacaClickListener);
tombolshare.setOnClickListener(shareClickListener);
rl2 = (RelativeLayout) itemView.findViewById(R.id.relmasjid);
}
private View.OnClickListener bacaClickListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
teksbaca = (Button) v.findViewById(R.id.buttonbaca);
// Baca 10x
if( getAdapterPosition() ==0 ) {
klik10--;
teksbaca.setText("Baca " + klik10 + "x");
if (klik10 <= 0)
{
// modify listItems however you want... add, delete, shuffle, etc
myAdapter.deleteItem(getAdapterPosition());
}
}
} // onclick
};
private View.OnClickListener shareClickListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
// Do button click handling here
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, mTitle.getText().toString() + "\n \n download aplikasinya di: http://www.tauhid.or.id" );
sendIntent.setType("text/plain");
Intent.createChooser(sendIntent,"Share via");
v.getContext().startActivity(sendIntent);
}
};
private View.OnClickListener mainViewClickListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
// Do button click handling here
}
};
}
DoaPagi.java
public class DoaPagi extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_doa_pagi);
// toolbar
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//this line shows back button
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
List<ModelDoa> rowListItem = getData();
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(DoaPagi.this);
RecyclerView mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView);
mRecyclerView.setLayoutManager(linearLayoutManager);
mRecyclerView.setHasFixedSize(true);
AdapterDoa rcAdapter = new AdapterDoa(rowListItem);
mRecyclerView.setAdapter(rcAdapter);
}
private List<ModelDoa> getData() {
String[] data = getResources().getStringArray(R.array.doapagi);
String[] baca = getResources().getStringArray(R.array.bacapagi);
List<ModelDoa> list = new ArrayList<ModelDoa>();
for (int i = 0; i < data.length; i++) {
list.add(new ModelDoa(data[i], baca[i], ModelDoa.DOA_PAGI));
}
return list;
}
// Agar back button pada halaman induk settings berfungsi
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
this.finish();
return true;
}
return super.onOptionsItemSelected(item);
}
}
UPDATE (FIX CODE) By: Krishna Sharma:
https://github.com/seadclark/RecyclerViewWithButtonClicks
Here is the fix. just update the ModelDoa constructor as below. I have verified myself and working as expected now. Also sent you pull request on github.
public ModelDoa(String name, String butong, int type) {
this.mName = name;
this.bName = butong;
this.mType = type;
String[] data = butong.split("\\s");
if (data.length > 0) {
String count = data[1].substring(0, data[1].length() - 1);
read10 = Integer.parseInt(count);
}
}
Instead of removing the item from your list AND updating the interface, have two methods. One of them (deleteItem) will only delete the item and the other (deleteItemAndUpdate) will delete the item and update the interface.
public void deleteItem(int position) {
mList.remove(position); // hapus list
}
public void deleteItemAndUpdate(int position) {
mList.remove(position); // hapus list
notifyItemRemoved(position); // hapus tampilan
}
In the future, you can decide whether you want to only remove the item from your list OR remove the item and update the UI.
EDIT 1:
You need to keep track of the amount of times that each item was clicked. We can call this value readCount. Every time that the item is clicked, we subtract 1 from this value. When this value reaches 0, we remove it from the list.
ModelDoa:
public class ModelDoa {
private int readCount = 10;
public int getReadCount() {
return this.readCount;
}
public void setReadCount(int readCount) {
this.readCount = readCount;
}
}
PagiViewHolder:
private View.OnClickListener bacaClickListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
teksbaca = (Button) v.findViewById(R.id.buttonbaca);
ModelDoa modelDoa = mAdapter.getItem(getAdapterPosition());
if (modelDoa != null) {
modelDoa.setReadCount(modelDoa.getReadCount() - 1);
if (modelDoa.getReadCount() <= 0) {
myAdapter.deleteItem(getAdapterPosition());
}
teksbaca.setText("Baca " + modelDoa.getReadCount() + "x");
}
}
};
AdapterDoa:
public ModelDoa getItem(int position) {
if (position > -1 && position < getItemCount()) {
return this.mList.get(position);
} else {
return null;
}
}
EDIT 2:
The idea is to set the readCount variable when you instantiate the object. You do not have multiple variables that do the same thing. You just change the single readCount variable to be either 7 or 10 when you are creating it and use the same getItem method when retrieving the model (not variable!) itself.
ModelDoa:
public class ModelDoa {
private String name;
private String butong;
private int type;
private int readCount;
public ModelDoa(String name, String butong, int type, int readCount) {
this.mName = name;
this.bName = butong;
this.mType = type;
this.readCount = readCount;
}
public int getReadCount() {
return this.readCount;
}
public void setReadCount(int readCount) {
this.readCount = readCount;
}
}
DoaPagi:
private List<ModelDoa> getData() {
String[] data = getResources().getStringArray(R.array.doapagi);
String[] baca = getResources().getStringArray(R.array.bacapagi);
List<ModelDoa> list = new ArrayList<ModelDoa>();
for (int i = 0; i < data.length; i++) {
// Here is where you would set the value of readCount.
list.add(new ModelDoa(data[i], baca[i], ModelDoa.DOA_PAGI, i));
}
return list;
}

how display string array content through recycleview adapter

I have this structure of json api:
{
seasons: [
{
seasonstitle: "Season 1",
titles: "S1E1; S1E2; S1E3",
},
{
seasonstitle: "Season 2",
titles: "S2E1; S2E2; S2E3",
},
]
}
and I'm trying to display the values of these two keys: seasonstitle and titles but as you see the titles key has multiple values so I parsing the json like this:
ParsingClass:
public final class JsonDetailSeries {
public static ArrayList<SeriesItem> getSimpleMovieStringsFromJson(Context context, String moviesJsonString)
throws JSONException {
final String SEASONS = "seasons";
final String SEASONTITLE = "seasonstitle";
final String TITLES = "titles";
ArrayList<SeriesItem> parsedMovieData = new ArrayList<>();
JSONObject moviesObject = new JSONObject(moviesJsonString);
JSONArray moviesArray = moviesObject.getJSONArray(SEASONS);
for (int i = 0; i < moviesArray.length(); i++) {
String seasontitle;
String titles;
moviesObject = moviesArray.getJSONObject(i);
seasontitle = moviesObject.getString(SEASONTITLE);
titles = moviesObject.getString(TITLES);
String[] titlesArrray = titles.split(Pattern.quote(";"));
for (int j=0; j<titlesArrray.length; j++) {
Log.i("titles ", "=" + titlesArrray[j]);
}
parsedMovieData.add(new SeriesItem(seasontitle, titlesArrray));
}
return parsedMovieData;
}
}
when I saw it in log cat it splits correctly like this:
titles = S1E1
titles = S1E2
titles = S1E3
and so on, in my custom arraylist class which I return the data for it:
public class SeriesItem implements Parcelable {
private String seasontitle;
private String[] titlesArrray;
public SeriesItem(String seasontitle, String[] titlesArrray) {
this.seasontitle = seasontitle;
this.titlesArrray = titlesArrray;
}
#Override
public void writeToParcel(Parcel out, int flags) {
out.writeString(seasontitle);
out.writeStringArray(titlesArrray);
}
private SeriesItem(Parcel in) {
this.seasontitle = in.readString();
this.titlesArrray = in.createStringArray();
}
public SeriesItem() {
}
#Override
public int describeContents() {
return 0;
}
public static final Creator<SeriesItem> CREATOR = new Creator<SeriesItem>() {
#Override
public SeriesItem createFromParcel(Parcel in) {
return new SeriesItem(in);
}
#Override
public SeriesItem[] newArray(int i) {
return new SeriesItem[i];
}
};
public String getSeasontitle() {
return seasontitle;
}
public String[] gettitlesArrray() {
return titlesArrray;
}
}
when I debug this class the data of titlesArrray recevied well each title split from the other one
so I'm trying to display this data in recyleview like this way:
Season1
S1E1
S1E2
S1E3
Season2
S2E1
S2E2
S2E3
so this is my adapter of recycleview:
public class SeriesAdapter extends RecyclerView.Adapter<SeriesAdapter.RecyclerViewHolder> {
ArrayList<SeriesItem> mMoviesItems;
private Context context;
private final SeriesAdapterOnClickHandler mClickHandler;
public interface SeriesAdapterOnClickHandler {
void onClick(SeriesItem movie);
}
public SeriesAdapter(SeriesAdapterOnClickHandler clickHandler) {
mClickHandler = clickHandler;
}
class RecyclerViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public final TextView seasontitle;
public final ListView titlesArray;
public RecyclerViewHolder(View view) {
super(view);
seasontitle = (TextView)itemView.findViewById(R.id.seasontitle);
titlesArray = (ListView) itemView.findViewById(R.id.titlesArray);
view.setOnClickListener(this);
}
#Override
public void onClick(View v) {
int adapterPosition = getAdapterPosition();
SeriesItem movie = mMoviesItems.get(adapterPosition);
mClickHandler.onClick(movie);
}
}
#Override
public RecyclerViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
context = viewGroup.getContext();
int layoutIdForListItem = R.layout.series_list_item;
LayoutInflater inflater = LayoutInflater.from(context);
boolean shouldAttachToParentImmediately = false;
View view = inflater.inflate(layoutIdForListItem, viewGroup, shouldAttachToParentImmediately);
return new RecyclerViewHolder(view);
}
#Override
public void onBindViewHolder(RecyclerViewHolder holder, int position) {
holder.seasontitle.setText(String.valueOf(mMoviesItems.get(position).getSeasontitle()));
holder.titlesArray.setText(String.valueOf(mMoviesItems.get(position).gettitlesArrray()));
}
#Override
public int getItemCount() {
if (null == mMoviesItems)
return 0;
else {
return mMoviesItems.size();
}
}
public void setMovieData(ArrayList<SeriesItem> movieData) {
mMoviesItems = movieData;
notifyDataSetChanged();
}
}
I tried to include a listview to display the titlesArray inside this recycleview and the problem is with this line:
holder.titlesArray.setText(String.valueOf(mMoviesItems.get(position).gettitlesArrray()));
I can't use setText for ListView so how can to display the titlesArray content inside this recycleview?
I tried to include a listview to display the titlesArray inside this recycleview
Do not do that.
What you want to do is handle two different types, the season and the episode. This question that will help you with that.
How to create RecyclerView with multiple view type?
Use Gson to parse Json instead of the native, it is much easier to implement.

Android java.lang.IllegalArgumentException: Duplicate key in ArrayMap: null

I'm getting this error
Caused by java.lang.IllegalArgumentException: Duplicate key in ArrayMap: null at android.util.ArrayMap.validate(ArrayMap.java:550) at android.os.Parcel.readArrayMapInternal(Parcel.java:2486) at android.os.BaseBundle.unparcel(BaseBundle.java:221) at android.os.BaseBundle.containsKey(BaseBundle.java:269) at com.example.fragments.QuestionSwipeFragment.handleBundle(SourceFile:197)
not in my current device but it is coming from crashlytics, but I can't regenerate this issue in my own device tried all possible ways but can't get this same error in my device, below is my code, answers would be really appreciated.
public class QuestionSwipeFragment extends DialogFragment {
private View mRootView;
private int mPosition;
private List<ResourceModel> mResourceList;
private QuestionSwipePagerAdapter mQuestionSwipePagerAdapter;
private ViewPager mPager;
private int mSelectedChapterId;
private int mSelectedSectionId;
private int mSelectedSubSectionId;
private boolean mSelectedFavourite;
private boolean mIsFavourite;
private boolean mIsPagination;
private int mCurrentPage;
private int mTotalPage;
int mResourcePageNo;
int mMarkId;
int mDifficulties;
private int mFragmentType;
private int mFragType;
private PaginationParams mPaginationParams = new PaginationParams();
private static final int RESOURCE_ALL = -1;
private boolean onDestroy = false;
private static final String API_TYPE_PAGINATION = "pagination";
public QuestionSwipeFragment() {
// Required empty public constructor
}
public static DialogFragment newInstance(List<ResourceModel> mResourceList, int id, int fragType, boolean isFavourited, boolean isPaginationRequest,
int chapterId, int sectionId,
int resourcePageNo, int markId,
int difficulties, int currentPage,
int totalPage) {
Bundle bundle = new Bundle();
QuestionSwipeFragment fragment = new QuestionSwipeFragment();
bundle.putParcelableArrayList(Constants.QUESTION_SWIPE_RESOURCE_LIST, (ArrayList<? extends Parcelable>) mResourceList);
bundle.putInt(Constants.QUESTION_SWIPE_RESOURCE_LIST_POSTION, id);
bundle.putInt(Constants.QUESTION_SWIPE_TYPE_FRAGMENT, fragType);
bundle.putBoolean(Constants.QUESTION_SWIPE_ISFAVOURITED, isFavourited);
bundle.putBoolean(Constants.QUESTION_SWIPE_ISPAGINATIONREQUEST, isPaginationRequest);
bundle.putInt(Constants.QUESTION_SWIPE_SELECTED_CHAPTER_ID, chapterId);
bundle.putInt(Constants.QUESTION_SWIPE_SELECTED_SECTION_ID, sectionId);
bundle.putInt(Constants.QUESTION_SWIPE_RESOURCEPAGE_NO, resourcePageNo);
bundle.putInt(Constants.QUESTION_SWIPE_MARKID, markId);
bundle.putInt(Constants.QUESTION_SWIPE_DIFFICULTIES, difficulties);
bundle.putInt(Constants.QUESTION_SWIPE_CURRENTPAGE, currentPage);
bundle.putInt(Constants.QUESTION_SWIPE_TOTALPAGE, totalPage);
fragment.setArguments(bundle);
return fragment;
}
public static DialogFragment newInstance(List<ResourceModel> mResourceList, int position, int fragType,
int selectedChapterId, int selectedSectionId, int selectedSubSectionId, int currentPage, int totalPage) {
Bundle bundle = new Bundle();
QuestionSwipeFragment fragment = new QuestionSwipeFragment();
bundle.putParcelableArrayList(Constants.QUESTION_SWIPE_RESOURCE_LIST, (ArrayList<? extends Parcelable>) mResourceList);
bundle.putInt(Constants.QUESTION_SWIPE_RESOURCE_LIST_POSTION, position);
bundle.putInt(Constants.QUESTION_SWIPE_TYPE_FRAGMENT, fragType);
bundle.putInt(Constants.QUESTION_SWIPE_SELECTED_CHAPTER_ID, selectedChapterId);
bundle.putInt(Constants.QUESTION_SWIPE_SELECTED_SECTION_ID, selectedSectionId);
bundle.putInt(Constants.QUESTION_SWIPE_SELECTED_SUBSECTION_ID, selectedSubSectionId);
bundle.putInt(Constants.QUESTION_SWIPE_CURRENTPAGE, currentPage);
bundle.putInt(Constants.QUESTION_SWIPE_TOTALPAGE, totalPage);
bundle.putInt(Constants.QUESTION_SWIPE_CURRENTFRAGMENT, fragType);
fragment.setArguments(bundle);
return fragment;
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
handleBundle(getArguments());
setStyle(DialogFragment.STYLE_NORMAL, R.style.MyMaterialTheme);
}
//the below method is causing IllegalArgumentException
private void handleBundle(Bundle bundle) {
if (bundle != null) {
if (bundle.containsKey(Constants.QUESTION_SWIPE_RESOURCE_LIST)) {
mResourceList = bundle.getParcelableArrayList(Constants.QUESTION_SWIPE_RESOURCE_LIST);
mPosition = bundle.getInt(Constants.QUESTION_SWIPE_RESOURCE_LIST_POSTION);
mFragType = bundle.getInt(Constants.QUESTION_SWIPE_TYPE_FRAGMENT);
mSelectedChapterId = bundle.getInt(Constants.QUESTION_SWIPE_SELECTED_CHAPTER_ID);
mSelectedSectionId = bundle.getInt(Constants.QUESTION_SWIPE_SELECTED_SECTION_ID);
mSelectedSubSectionId = bundle.getInt(Constants.QUESTION_SWIPE_SELECTED_SUBSECTION_ID);
mIsFavourite = bundle.getBoolean(Constants.QUESTION_SWIPE_ISFAVOURITED);
mIsPagination = bundle.getBoolean(Constants.QUESTION_SWIPE_ISPAGINATIONREQUEST);
mCurrentPage = bundle.getInt(Constants.QUESTION_SWIPE_CURRENTPAGE);
mTotalPage = bundle.getInt(Constants.QUESTION_SWIPE_TOTALPAGE);
mResourcePageNo = bundle.getInt(Constants.QUESTION_SWIPE_RESOURCEPAGE_NO);
mMarkId = bundle.getInt(Constants.QUESTION_SWIPE_MARKID);
mDifficulties = bundle.getInt(Constants.QUESTION_SWIPE_DIFFICULTIES);
mFragmentType = bundle.getInt(Constants.QUESTION_SWIPE_CURRENTFRAGMENT);
}
}
}
And below is the code where i am starting this fragment from adapter
private void setonClickListeners(ResourceQuestionsViewHolder viewHolder, final int position) {
viewHolder.mContainerView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
DialogFragment questionSwipeFragment = QuestionSwipeFragment.newInstance(getExtractResourceInfo(position).getExtractedList(), getExtractResourceInfo(position).getPosition(), Constants.QB_DETAILS_FRAGMENT, isFavourited, isPaginationRequest, chapterId, sectionId, resourcePageNo, markId, difficulties, mCurrentPage, mTotalPage);
questionSwipeFragment.show(((QuestionBankActivity) mContext).getSupportFragmentManager(), "dialog");
}
});
}
private void setonLongClickListener(SubSectionResourceQuestionsViewHolder viewHolder, final int position) {
viewHolder.mContainerView.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
DialogFragment questionBankFragment = QBSubSectionDetailFragment.newInstance(mResourceList, false, position);
questionBankFragment.show(((SynopsisActivity) mContext).getSupportFragmentManager(), "dialog");
return true;
}
});
}
When I have this problem it's actually caused by other exceptions
My problem is caused by starting an Activity that is not exported
Solution:
Check that your passed argument does have multiple null keys
Check whether an Activity that is not set to export has been started (for starting other apps)
You can set references directly to fragments without passing them through bundle
#jonathan3087
Please check below things in your Parcelable class:
Order of your Parcelable class's field in writeToParcel()
Key name or reusing key or not
check proguard keep

Custom android component

I am trying to make a custom android component. For that reason I have make my class extend "View", but the class is already extending "BaseAdapter". The component should be something like this: http://www.brightec.co.uk/blog/android-listview-alphabet-scroller but it should appear in the Palette under the CustomView component.
This is the class that should inherit View instead of BaseElement:
public class AlphabetListAdapter extends BaseAdapter {
public static abstract class Row {}
public static final class Section extends Row {
public final String text;
public Section(String text) {
this.text = text;
}
}
public static final class Item extends Row {
public final String text;
public Item(String text) {
this.text = text;
}
}
private List<Row> rows;
public void setRows(List<Row> rows) {
this.rows = rows;
}
}
And this is the class that instantiates it, and uses it as an adapter.
public class MainActivity extends ListActivity {
private AlphabetListAdapter adapter = new AlphabetListAdapter();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.list_alphabet);
for (String country : countries) {
rows.add(new Item(country));
}
adapter.setRows(rows);
setListAdapter(adapter); //not able to do this with a class that extends View
updateList();
}
}
The whole source is available on: https://github.com/brightec/AlphabetScroller
(ths is not my code, it is an example I found online)
Is there a way to do that? I have tried to Google it, but it seems like it is not possible for a single class to extend two classes. Is there another way of making this project to act like a single component?
I think you need to create the class by extending View first then include your AlphabetListAdapter in as a member variable and expose that through getters and setters.
public class AlphabeticListView extends View {
private ListView mListView;
private LinearLayout mSideIndex;
private AlphabetListAdapter adapter;
private List<Object[]> alphabet;
private HashMap<String, Integer> sections;
private static float sideIndexX;
private static float sideIndexY;
private int sideIndexHeight;
private int indexListSize;
private GestureDetector mGestureDetector;
public AlphabeticListView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
public AlphabeticListView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public AlphabeticListView(Context context) {
super(context);
init();
}
private void init() {
Context context = getContext();
mGestureDetector = new GestureDetector(getContext(),
new SideIndexGestureListener());
mListView = new ListView(context); // TODO add layoutParams and other attributes you might need.
mSideIndex = new LinearLayout(context); // TODO add layoutParams and other attributes you might need.
}
public AlphabetListAdapter getAdapter() {
return adapter;
}
public void setAdapter(AlphabetListAdapter adapter) {
mListView.setAdapter(adapter);
this.adapter = adapter;
}
public List<Object[]> getAlphabet() {
return alphabet;
}
public void setAlphabet(List<Object[]> alphabet) {
this.alphabet = alphabet;
}
public HashMap<String, Integer> getSections() {
return sections;
}
public void setSections(HashMap<String, Integer> sections) {
this.sections = sections;
}
public void updateList() {
mSideIndex.removeAllViews();
indexListSize = alphabet.size();
if (indexListSize < 1) {
return;
}
int indexMaxSize = (int) Math.floor(mSideIndex.getHeight() / 20);
int tmpIndexListSize = indexListSize;
while (tmpIndexListSize > indexMaxSize) {
tmpIndexListSize = tmpIndexListSize / 2;
}
double delta;
if (tmpIndexListSize > 0) {
delta = indexListSize / tmpIndexListSize;
} else {
delta = 1;
}
TextView tmpTV;
for (double i = 1; i <= indexListSize; i = i + delta) {
Object[] tmpIndexItem = alphabet.get((int) i - 1);
String tmpLetter = tmpIndexItem[0].toString();
tmpTV = new TextView(getContext());
tmpTV.setText(tmpLetter);
tmpTV.setGravity(Gravity.CENTER);
tmpTV.setTextSize(15);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT, 1);
tmpTV.setLayoutParams(params);
mSideIndex.addView(tmpTV);
}
sideIndexHeight = mSideIndex.getHeight();
mSideIndex.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
// now you know coordinates of touch
sideIndexX = event.getX();
sideIndexY = event.getY();
// and can display a proper item it country list
displayListItem();
return false;
}
});
}
public void displayListItem() {
sideIndexHeight = mSideIndex.getHeight();
// compute number of pixels for every side index item
double pixelPerIndexItem = (double) sideIndexHeight / indexListSize;
// compute the item index for given event position belongs to
int itemPosition = (int) (sideIndexY / pixelPerIndexItem);
// get the item (we can do it since we know item index)
if (itemPosition < alphabet.size()) {
Object[] indexItem = alphabet.get(itemPosition);
int subitemPosition = sections.get(indexItem[0]);
// ListView listView = (ListView) findViewById(android.R.id.list);
mListView.setSelection(subitemPosition);
}
}
class SideIndexGestureListener extends GestureDetector.SimpleOnGestureListener {
#Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
float distanceY) {
sideIndexX = sideIndexX - distanceX;
sideIndexY = sideIndexY - distanceY;
if (sideIndexX >= 0 && sideIndexY >= 0) {
displayListItem();
}
return super.onScroll(e1, e2, distanceX, distanceY);
}
}
}
And in your MainActivity add the following:
AlphabeticListView listView =
(AlphabeticListView) findViewById(R.id.alphabeticListView1);
listView.setAdapter(adapter);
listView.setAlphabet(alphabet);
listView.setSections(sections);
listView.updateList();
In Java, a Class can only extend one Class directly (but implement several interfaces).
Since you're not submitting your own code, it's hard to give you some substantial feedback, but here are some thoughts:
Can you make your custom View as an XML, and include your class with the "tools:context" attribute?
Can't you just build the functionality you want in an Activity or a Fragment? And does you class have to extend BaseAdapter? Can you use composition instead?
I don't know if this helps you at all, but best of luck.

Categories

Resources