I have a Fragment with some ImageViews, if I click on one of this ImageViews the app open a new activity where the just clicked "target" image is at the top of it.
In the first place I put the ImageView in the new Activity directly in the parent layout.
Now in this activity I've set a custom Header as the first item of the RecyclerView, the "target" ImageView is in this new header.
Now the transition doesn't work anymore. I've thought that the content of the RecyclerView is drawn later, so I've tryed with
ActivityCompat.postponeEnterTransition(this);
before setContentView (I dont know if it's correct)
and
ActivityCompat.startPostponedEnterTransition(mContext);
in onBindViewHolder of the RecyclerView.
But it doesn't work...what can I do?
I solved by using
setEnterSharedElementCallback(new SharedElementCallback() {
#Override
public void onMapSharedElements(List<String> names, Map<String, View> sharedElements) {
sharedElements.put("profile_user_img", image);
super.onMapSharedElements(names, sharedElements);
}
});
in conjunction with postponeEnterTransition and startPostponedEnterTransition
Related
I have a main recyclerview,which displays my main cardview. Now this main cardview got a child recyclerview inside,which holds the child cardview.
Now when i click on the anyof the main cardview,the child recyclerview with child cardviews become visible.
If i click that main cardview again,then the child recyclerview becomes invisible.
Now what's happening is, if i click a main carview,then its child recyclerview will be come visible.
Now if i click another main cardview,then its child recyclerview will appear. like this
What i want is,if i click another main cardview,then,if any other childviews are visible , then it should become invibsle. In another words,the child rewcyclerview of the main cardview which i click should only be open. All others child recyclerviews should be invisible/ close.
Now what i want is a way to access all the main carviews in the main recyclerview,when i click a particular main cardview,so that i cam make the child recyclerview of all those main cardviews invisible.
Hope i made my point clear.
I want only one childview open at a time like this..
This is the onBindViewHolder of main Recyclerview holder adapter
#Override
public void onBindViewHolder(#NonNull final MainHolder holder, final int position) {
MSeasonTanks mSeasonTanks=mSTankList.get(position);
MoultingDataEntry moultingDataEntry=moultList.get(position);
holder.textViewOne.setText("Tank Number : "+mSeasonTanks.getTName());
ChildRVAdapter childRVAdapter=new ChildRVAdapter(moultingDataEntry,mSeasonTanks.getTID(),holder);
holder.childRecyclerView.setLayoutManager(new LinearLayoutManager(context));
holder.imageViewDirection.setImageResource(R.drawable.ic_expand);
holder.cardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(holder.childRecyclerView.getVisibility()==View.VISIBLE){
holder.childRecyclerView.setVisibility(View.GONE);
holder.imageViewDirection.setImageResource(R.drawable.ic_expand);
}else{
holder.childRecyclerView.setVisibility(View.VISIBLE);
holder.imageViewDirection.setImageResource(R.drawable.ic_collapse);
}
}
});
holder.childRecyclerView.setAdapter(childRVAdapter);
}
So on the main carview onClick method to access all the main cardviews,so that i can get their child recyclerviews invisible if its open.
Thanks in advance..
What I will Suggest is.
-> Suppose you have data for the main Recyclerview like
MainRecyclerItemData, It should have one boolean flag, isExpanded
-> isExpanded = true (Inner Recyclerview is Visible)
-> isExpanded = false (Inner Recyclerview is hidden)
-> Now When User click on main recycler item, Pass MainRecyclerItemData's id for the clicked item to your activity via interface to method suppose (OuterItemClicked(String id)).
-> Now loop the wholelist, and for the wholelist make isExpanded = false except for the item with the clcked id (for it make it true).
-> Now call adapter.notifydatasetchanged()
//In onBindViewHolder() you should have code to handle isExpanded flag,
if(isExpanded){
// Show inner recyclerview
}else{
// Hide inner recyclerview
}
So i have a recycler view loaded with items containing text and image and a checkbox. All the data is loaded just fine initially including the images using picasso. The checkbox is initially hidden, once i tap a button, which is not part of the recycler view. The checkboxes should appear in all the items of recycler view. Everything works fine except for the fact that the images disappear once i do that.
The way i am doing it is that i set the adapter to my recyclerview to null and then initialize a new recycler view adapter which has checkboxes visible and set it to my recycler view.
The same thing happens if i try to search for a particular list item using a search bar on top. Any idea why? Here is the code about how i am setting the adapter to my recycler view.
// set the adapter to null on cards list view.
cards_list_view.setAdapter(null);
// Initialize the adapter again.
deckCardRecycleAdapter = new DeckCardRecycleAdapter(getActivity(), cards_list, show_checkbox);
// Set the adapter again to list view.
cards_list_view.setAdapter(deckCardRecycleAdapter);
And here is my onBindViewHolder function in adapter.
#Override
public void onBindViewHolder(final ViewHolder viewHolder, final int position) {
typeface = Typeface.createFromAsset(context.getAssets(), "fonts/futura-medium.otf");
viewHolder.user_name.setTypeface(typeface);
viewHolder.user_name.setText(cards.get(position).getName().toString());
viewHolder.position.setTypeface(typeface);
viewHolder.position.setText(cards.get(position).getPosition().toString());
viewHolder.dot.setTypeface(typeface);
viewHolder.event_saved.setTypeface(typeface);
if(cards.get(position).getEvent_name().toString().equals("None")) {
viewHolder.event_saved.setVisibility(View.GONE);
viewHolder.dot.setVisibility(View.GONE);
}
else
viewHolder.event_saved.setText(cards.get(position).getEvent_name().toString());
viewHolder.date_saved.setTypeface(typeface);
String timestamp = cards.get(position).getTimestamp().toString();
viewHolder.date_saved.setText(toDate(timestamp));
if(cards.get(position).image_url.toString().equals("None"))
viewHolder.user_image.setImageResource(R.drawable.anonymous);
else {
String url_image = cards.get(position).image_url.toString();
Picasso.with(this.context).cancelRequest(viewHolder.user_image);
Picasso.with(context).load(url_image).into(new Target() {
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
viewHolder.user_image.setImageBitmap(bitmap);
cards.get(position).setImage_url(getStringImage(bitmap));
}
#Override
public void onBitmapFailed(Drawable errorDrawable) {
}
#Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
}
});
}
Please help. Thanks in advance.
I don't think it's a good idea to reload data each time, it's make a lot of performance instead you can create interface and let the item listening to it, and just with one line of code you can change the visibility
Check this answer
interface Listener {
public void onVisibilityChanged(bool visible);
}
create an interface (set bool parameter for visible/invisible)
Create separate class for manage listener's (like this)
add listener for each item (make checkbox visible or invisible)
remove listener when item removed (avoid NullpointException)
clear listener's if recycler reset (avoid NullpointException)
call the method that have foreach and all the listeners will be triged
My problem is to understand how RecyclerView works.. I have RecyclerView with a little bit complicated item in every row, but the main thing is that Item has a child ImageView and LinearLayout. I want to press ImageView and set Visibility of LinearLayout to GONE or VISIBLE and rotate my ImageView. I tried to do this in my onBindViewHolder:
holder.mIVExpandBtn.setOnClickListener(new OnClickListener() {
boolean isOpen = false;
#Override
public void onClick(View v) {
if (isOpen) {
CounterListAdapter.this.notifyItemChanged(position);
holder.mLLDetails.setVisibility(GONE);
holder.mDivider.setVisibility(VISIBLE);
holder.setArrowUp(false);
isOpen = false;
counterItem.setDetailsOpened(false);
} else {
holder.mLLDetails.setVisibility(VISIBLE);
holder.mDivider.setVisibility(GONE);
holder.setArrowUp(true);
isOpen = true;
counterItem.setDetailsOpened(true);
}
}
});
And I have some problems here.
I have a boolean variable inside OnClickListener, I know its wrong, so it changes only one time when I expand my LinearLayout. If I make this boolean global variable, if I expand one row of RecyclerView isOpen = true for any other item and it doesn't expand itself when I click on ImageView.. Where should I place this boolean?
And the second question - how can I save the state of my RecyclerView rows on screen rotation? For example I expanded one of my rows, LinearLayout.setVisibility(VISIBLE), change screen orientation and its closed.
For your first problem, you should put your boolean variable where you also define your views, i.e., inside your ViewHolder, ir order that onClick you call the boolean this way
if(holder.isOpen)
In this way you keep the reference of each boolean to each row.
For your second problem, the solution is pretty simple. In your manifest, in the activity where you have your RecyclerView, define the following:
android:configChanges="keyboardHidden|orientation|screenSize"
This prevents your activity from being recreated on configuration change in case you rotate the screen, so the activity will keep it's state and your RecyclerView will therefor not be recreated along with your adapter.
Notice that this means that, if your activity is not recreated, onPause, onStop, etc, will not run. This is only for screen rotation, your activity will still run the method onConfigurationChanged() which is where you should define any changes you need in case the screen rotates.
You better put the OnClickListener in the Holder class, something like this:
private class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
#Override
public void onClick(View view) {
....
}
About how to save state I think all things that define the rows should be saved in the array you pass to the adapter contructor, you can add fields in the array item object that save VISIBILITY state of the row views.
On screen rotation then two options:
1 - as #Ricardo said avoiding Activity recreation
2 - onSaveInstanceState / onRestoreInstanceStates save/restore the array that define the rows .. my prefered method for that is to use JSON and put it in a String that can be saved/restored in the Bundle.
I have a recycler view containing some images and when i click on an image it opens a new activity with a view pager to show those images.
this openning contains a shared element transition. now when press the back button i want to change the transiting view to the currently viewing image.
how can i do this
I already tried setExitSharedElementCallback on the first activity which updates List<String> names and Map<String, View> sharedElements on onMapSharedElements to appropriate ones. but still no transition happens.
is there anything else I should do?
after more works i find out that i should also add
setEnterSharedElementCallback(new SharedElementCallback() {
#Override
public void onMapSharedElements(List<String> names, Map<String, View> sharedElements) {
// update names and sharedElements
}
}
to the second activity to update its transition views.
I created an expandable listview based on this link. Its just working fine. Now what i want is
1) How to make a childview to link another sub-child view
2) The sub- child view should be open as a new list view on the window(Right side of the view) is my expected layout. I googled but couldn't find how to achieve this. Please help me in achieving this. Thanks in advance.
You'll need to specify and handle onClick event of ListView row items.
Then you'll open a new Activity, based on the item clicked.
Parameters for new activity are supplied through intent extras, the new activity can use these values to get data from cloud or process the values to show certain results.
I've used CustomAdapter class several times to handle this scenario.
class Ocl implements OnClickListener{
#Override
public void onClick(View v) {
Intent intDetail = new Intent(getActivity(), PartDetail.class);
intDetail.putExtra(_ID, mParts[position].getSPr());
intDetail.putExtra(_LOT, mParts[position].getLotID());
intDetail.putExtra(_QTY, mParts[position].getQty());
intDetail.putExtra(_UID, mParts[position].getPartID());
startActivity(intDetail);
}
}
So, do you want your first child to expand into another ListView? Or maybe just open another Activity/Fragment that contains the matching ListView?
In case you want to the the first, you could design a CustomLayout for the Childview, which on OnClick expands, and changes its content to a specific ListView.
Otherwise you would just open up another ListView with data depending on Which Child in First List was Clicked.
Well, i am using some Like that to enlarge ChildViews on Click to show me detailed information.
Im using a Class to wrap my Data named Row. These Rows indicate if they are clickable and if so, the ListView will allow clicks on the rows. A Click will then be handled by the Class itself, making the displayed Text longer(more Detailed). And in order to relayout the items, you need to call notifyDataSetChanged.
#Override
public void onClick(Context context, MyExpandableListAdapter mela) {
this.setBig(!isBig());
mela.notifyDataSetChanged();
}
So, i would handle the row state (expanded/normal) in the getView Method of parents Adapter, to decide which childLayout i inflate.
would looke something like this
public View getView (args...) {
Object data = getItem(position);
if (data.isExpanded()) {
//inflate ListView Layout, create Addapter fill it....
} else {
//show some title or whatever to identify row.
}
}