I'm trying to create a curved layout to list some elements and adapt it to the android wear, but the Google Android Developers page about it is very unclear. Did anyone manage to create a curved layout?
This is the Google Developers that I'm talking about:
https://developer.android.com/training/wearables/ui/lists.html#creating
If you have any tips to realize it, I'd be glad to see it.
I hope you figured it out by now, but if not, here are the steps with some example code:
in your round\activity_main.xml use android.support.wear.widget.WearableRecyclerView as the root/main element:
<?xml version="1.0" encoding="utf-8"?>
<android.support.wear.widget.WearableRecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/rv_test"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- ... -->
</android.support.wear.widget.WearableRecyclerView>
Then on the MainActivity extend WearableActivity:
import android.os.Bundle;
import android.support.wearable.activity.WearableActivity;
import android.support.wear.widget.WearableRecyclerView
public class MainActivity extends WearableActivity {
private android.support.wear.widget.WearableRecyclerView wearableRecyclerView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
wearableRecyclerView = findViewById(R.id.rv_test);
wearableRecyclerView.setLayoutManager(new WearableLinearLayoutManager(MainActivity.this));
wearableRecyclerView.setEdgeItemsCenteringEnabled(true);
}
...
}
You need to make sure you are using the right import for WearableRecyclerView (android.support.wear.widget.WearableRecyclerView) on both the xml and java
Next (which isn't explained in the Developers webpage is creating a ViewHolder:
1 - First create an xml layout (here called circle_view.xml):
<?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="match_parent">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/close_button"
android:id="#+id/circledImageView"/>
</LinearLayout>
2 - Then create a java class (here called TestHolder.java) and extended it to RecyclerView.ViewHolder:
public class TestHolder extends RecyclerView.ViewHolder {
protected ImageView imageView;
public TestHolder(View itemView) {
super(itemView);
imageView = (ImageView) itemView.findViewById(R.id.circledImageView);
}
}
Then back in the MainActivity.java add the following below the wearableRecyclerView.setEdgeItemsCenteringEnabled(true); inside onCreate:
RecyclerView.Adapter<TestHolder> testHolderAdapter = new RecyclerView.Adapter<TestHolder>() {
#Override
public TestHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.circle_view, parent, false);
return new TestHolder(view);
}
#Override
public void onBindViewHolder(TestHolder holder, int position) {
}
#Override
public int getItemCount() {
//change return number to desired number of items or an array size or list length
return 5;
}
};
wearableRecyclerView.setAdapter(testHolderAdapter);
Thats all, run your app in a rounded wear emulator or on a round/round-with-chin watch and enjoy the curvy list
Related
I'm trying to build a word-to-word RTL language ebook application. The data for the ebook is stored in an Sqlite database. After vigorous searching I found Flexbox layout suitable to my need in order to display my data in my required format. The following link helped me out: Android GridLayout with dynamic number of columns per row But the issue is that if the data passed in the view is large, then partial data is being displayed. If the data passed is small, then i have no issues at all.
Here is the adapter code:
public class VerseAdapter extends RecyclerView.Adapter<VerseAdapter.ViewHolder> {
private List<verseItem> items;
private Context context;
wordsAdapter sAdapter;
GridLayoutManager layoutManager;
public VerseAdapter(List<verseItem> items, Context context) {
this.items = items;
this.context = context;
}
// This method is used to attach
// custom layout to the recycler view
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View vw = LayoutInflater.from(parent.getContext()).inflate(R.layout.verse_row, parent, false);
return new ViewHolder(vw);
}
// This method is used to set the action
// to the widgets of our custom layout.
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
verseItem item = items.get(position);
ArrayList<wordsModel> models = new ArrayList<>(item.getWordsModelList());
String ayahnum = "" + item.getAyah();
holder.ayah.setText(ayahnum);
holder.verses_telugu.setText(item.getVerses_telugu());
// FlexboxLayoutManager code:
FlexboxLayoutManager layoutManager = new FlexboxLayoutManager(context);
layoutManager.setFlexDirection(FlexDirection.ROW_REVERSE);
layoutManager.setJustifyContent(JustifyContent.FLEX_START);
ViewHolder.wordsrecyclerView.setLayoutManager(layoutManager);
sAdapter = new wordsAdapter(models);
ViewHolder.wordsrecyclerView.setAdapter(sAdapter);
sAdapter.notifyItemChanged(position);
holder.setIsRecyclable(false);
}
#Override
public int getItemCount() {
return items.size();
}
#Override
public int getItemViewType(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
static class ViewHolder extends RecyclerView.ViewHolder {
TextView ayah;
TextView verses_telugu;
public static RecyclerView wordsrecyclerView;
public ViewHolder(View itemView) {
super(itemView);
ayah = itemView.findViewById(R.id.ayah);
verses_telugu = itemView.findViewById(R.id.telugu_line);
wordsrecyclerView = itemView.findViewById(R.id.words_RV_id);
}
}
}
Here is my layout file:
<?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"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="#+id/ayah"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:layout_margin="5dp"
android:textAlignment="viewStart"
android:textColor="#27A82C"
android:textSize="18sp"
android:textStyle="bold" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/words_RV_id"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/telugu_line"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:layout_margin="5dp"
android:textAlignment="textStart"
android:textSize="16sp"
android:textStyle="bold" />
</LinearLayout>
This is how the final result show actually look like:
This is how my app looks like:
Now if you notice from the screenshots, the data that i'm trying to display is same. But in my app, not all words are being displayed as you can notice.
Another thing i have noticed is for larger data if the screen orientation is vertical the maximum lines i can see is 10 and if it is horizontal i can see 6 lines at max. These number of lines are fixed for all the places where the data is large. If the data is smaller it is displayed in the exact number of lines required and as mentioned earlier I have no issues at all.
Hoping someone helps me out soon. Thanks in advance. (:
I have a root recyclerview and each item is populated with this layout:
<?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"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<TextView
android:id="#+id/headerText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/accent_gradient"
android:ellipsize="end"
android:maxLines="1"
android:padding="8dp"
android:paddingStart="16dp"
android:text="My original"
android:textColor="#color/colorWhite"
android:textSize="14sp" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rootRecycler"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
/>
</LinearLayout>
As you can see, there is another recylcerview within each item. I wanted to achieve the effect of sectioned recyclerview with headers. (So Header > List Header > List)
Now each recyclerview is populated with this layout view:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<TextView
android:layout_toStartOf="#id/relativeLayout3"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:id="#+id/foodName_fv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="8dp"
android:text="Food name"
android:ellipsize="end"
android:maxLines="1"
android:textColor="#color/colorBlack"
android:textSize="18sp"
android:transitionName="Food_Name"/>
<TextView
android:layout_below="#id/foodName_fv"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:id="#+id/foodGrams_fv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:text="Grams"
android:textColor="#color/colorLightGrey"
android:textSize="15sp" />
<LinearLayout
android:id="#+id/relativeLayout3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:orientation="vertical"
android:layout_alignParentEnd="true"
>
<TextView
android:id="#+id/foodCalories_fv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="Calories"
android:textColor="#color/colorBlack"
android:textSize="18sp"
android:transitionName="Food_Cal"/>
<TextView
android:layout_gravity="center"
android:id="#+id/calText_fv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:paddingBottom="8dp"
android:text="#string/calText_fv"
android:textColor="#color/colorLightGrey"
android:textSize="14sp" />
</LinearLayout>
</RelativeLayout>
This is a fairly simple layout but for some odd reason the child recyclerview takes soo much time to inflate these rows. I did some testings and it took (on average) 1200 ms to load 300 rows!
Now the weirdest thing is that before this code i had a plain listview (without any sections and headers, just a big list) and it loaded all these rows very fast. I have'nt changed nothing but this code (Converting it from listview with an adapter to recyclerview with an adapter) so it looks pretty strange to me, but i dont know i might be missing something here.
This is the onCreateViewHolder method:
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.food_view, parent, false);
return new ViewHolder(view);
}
In conclusion the child recyclerview takes too much time to do this work. And yes I am aware i can do "Lazy loading" but I want to figure out why the hell is it so slow?
EDIT 1:
Tried implementing it in a fresh new project, thought something with the broke somehow, but its still gave same results, also tried on my actual phone and not an emulator and still slow. I really want to figure out this one already because it seems very illogical.
EDIT 2:
Posting the adapters code for hamza khan:
Code for the root recyclerview:
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.ArrayList;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
public class SelectFoodRootRecyclerAdapter extends RecyclerView.Adapter<SelectFoodRootRecyclerAdapter.ViewHolder> {
private static final String TAG = "SelectFoodRootRecyclerAdapter";
private Context mContext;
private ArrayList<SectionedFoodGroup> items;
private ArrayList<SelectFoodChildRecyclerAdapter> adapters; //For filter use outside this class
RecyclerView.RecycledViewPool recycledViewPool;
public SelectFoodRootRecyclerAdapter(Context mContext) {
this.mContext = mContext;
items = new ArrayList<>();
adapters = new ArrayList<>();
recycledViewPool = new RecyclerView.RecycledViewPool();
SectionedFoodGroup section1 = new SectionedFoodGroup(mContext.getString(R.string.myFoods),
FoodsDBHelper.getAllFoodRows(Food.DBType.USER_CREATED_FOODS_DB.ordinal()));
SectionedFoodGroup section2 = new SectionedFoodGroup(mContext.getString(R.string.foods),
FoodsDBHelper.getAllFoodRows(Food.DBType.REGULAR_FOOD_DB.ordinal()));
addSection(section1);
addSection(section2);
}
private void addSection(SectionedFoodGroup sectionedFoodGroup){
if(sectionedFoodGroup.getFoods().size() > 0){
items.add(sectionedFoodGroup);
adapters.add(new SelectFoodChildRecyclerAdapter(mContext, sectionedFoodGroup.getFoods()));
}
}
public ArrayList<SelectFoodChildRecyclerAdapter> getAdapters(){
return adapters;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_sfa_viewholder, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
SectionedFoodGroup sectionedFoodGroup = items.get(position);
holder.headerText.setText(sectionedFoodGroup.getHeaderName());
holder.foodsRecycler.setAdapter(adapters.get(position));
holder.foodsRecycler.setRecycledViewPool(recycledViewPool);
}
#Override
public int getItemCount() {
return items != null ? items.size() : 0;
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView headerText;
RecyclerView foodsRecycler;
public ViewHolder(#NonNull View itemView) {
super(itemView);
headerText = itemView.findViewById(R.id.headerText);
foodsRecycler = itemView.findViewById(R.id.rootRecycler);
}
}
}
Code for the child recyclerview (the one containing all the actual rows):
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.TextView;
import java.text.DecimalFormat;
import java.util.ArrayList;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
public class SelectFoodChildRecyclerAdapter extends RecyclerView.Adapter<SelectFoodChildRecyclerAdapter.ViewHolder>{
private static final String TAG = "SelectFoodChildRecyclerAdapter";
private Context mContext;
private ArrayList<Food> original;
private DecimalFormat decimalFormat;
public SelectFoodChildRecyclerAdapter(Context mContext, ArrayList<Food> foods) {
this.mContext = mContext;
this.original = foods;
decimalFormat = new DecimalFormat("#.0");
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.food_view, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int foodPos) {
Food currFood = original.get(foodPos);
holder.foodName.setText(currFood.getName());
float grams = 100;
if(currFood.getAmount() != 0) grams = (float)currFood.getAmount();
int roundedGrams = (int)Math.round(grams);
holder.foodGrams.setText(roundedGrams +" "+ mContext.getResources().getString(R.string.gramsWord));
float caloriesToShow = (float)currFood.getCalories();
holder.foodCalories.setText(decimalFormat.format(caloriesToShow));
}
#Override
public int getItemCount() {
return original != null ? original.size() : 0;
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView foodName;
TextView foodGrams;
TextView foodCalories;
public ViewHolder(View itemView) {
super(itemView);
foodName = itemView.findViewById(R.id.foodName_fv);
foodGrams = itemView.findViewById(R.id.foodGrams_fv);
foodCalories = itemView.findViewById(R.id.foodCalories_fv);
}
}
}
The calling activity onCreate method:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_select_food);
foodsRecyclerView = findViewById(R.id.rootRecycler);
selectFoodRootRecyclerAdapter = new SelectFoodRootRecyclerAdapter(this);
foodsRecyclerView.setAdapter(selectFoodRootRecyclerAdapter);
}
Again, as you can see all the code is fairly simple..
EDIT 3:
Ok so i've narrowed it down even more. I tried to do just one big recyclerview of the second layout and it worked fast. SOOO the problem must be with the first layout/the root recyclerview adapter code. but everything seems fine with it...
I really don't know what am I missing here!! Thanks for any kind of help!
Thanks!
Well, because no one was able to answer my question and I've found my answer then ill share it with other people who might look at this in the future and think, wow this is exactly what I need.
So.. It turns out using a RecyclerView within RecyclerView is a big no no. thats because the onCreateViewHolder method gets called as many times as your items array size, and thats very heavy, especially if you have a large list. (I think its the same as RecyclerView within a ScrollView) - So try to avoid using this type of implementation.
So what can you do?
Option 1 - Create a multi view RecylcerView adapter. that means that you have one adapter and it can handle multiple view types (perfect for what i wanted. 1 view type is a header and the second view type is another layout to act as my main row).
You can look it up in google to find good results on how to implement it but the main
So declare these variables:
private int VIEW_TYPE_HEADER = 0;
private int VIEW_TYPE_MAIN_ROW = 1;
Next override the next method, and what this basically does it gives each row a special int which we then can compare in onCreateViewHolder and decide which layout we want to inflate (e.g. If its going to be a header or a main row)
#Override
public int getItemViewType(int itemPos) {
if(items.get(itemPos) instanceof String){
return VIEW_TYPE_HEADER;
}
return VIEW_TYPE_MAIN_ROW;
}
On the onCreateViewHolder we can test to see what type of row we are dealing with and inflate accordingly.
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
if(viewType == VIEW_TYPE_HEADER){
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.header)_layout, parent, false);
return new HeaderViewHolder(view);
}
//Else a regular row.
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.main_row, parent, false);
return new MainViewHolder(view);
}
And of course make a separate view holder for each type.
Option 2 - Because I need only 2-3 sections, what i could also do is just "hardcode" it like this:
Create a TextView to be the header and below it a RecyclerView AND again 2-3 times. this approach is obviously less flexible but it works if you want some small.
Hope this'll help someone one day.
I am new to Android TV development. I don't know which type of fragment to use. I want two achieve layout similar to above screenshot as jiocinema. Somehow I have achieved it using a two xml fragments inside activity layout. Second fragments loads screenshot after hitting an API so it loads after some time. As can be seen in the above screenshot I want the layout in two parts..top one with details and some buttons and the bottom one is a list of screenshots of that movie.
In my case the problem is, bottom list part takes the focus on loading this particular screen after that on pressing up button or any button it never loses focus and never goes on the top part.
Note: below fragment loads asynchronously, as it hits an api for screenshot urls
May be I haven't used proper fragments for this particular layout. Can someone point me to the code or help me out in deciding what to use for this kind of layout. As it can be achieved but navigation is the main thing.
code
activity layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/photo_label_box">
<fragment
android:id="#+id/detail_layout"
android:layout_width="match_parent"
android:name="com.DetailsActivityGame$Detalfragment"
android:layout_height="200dp"></fragment>
<fragment
android:id="#+id/row_layout"
android:layout_width="match_parent"
android:layout_below="#+id/detail_layout"
android:name="com.DetailsActivityGame$SampleFragmentC"
android:layout_height="wrap_content"></fragment>
</RelativeLayout>
Thanks
Try to use the RowSupportFragment in V4 Support Fragment for desired output.
Divide layout into two parts layout with buttons, description and below scrolling layout(Represent by RowSupportFragment)
//----------------------detail_layout
<?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="match_parent"
android:background="#color/leader_background">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/main_layout"
//your own layout design for buttons and description
</RelativeLayout>
<fragment
android:name="FragmentScreenshots"
android:id="#+id/screenshot_fragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
//----------------Detailfragment--------------------
public static class Detailfragment extends Fragment {
public Detailfragment(){ }
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.detail_layout, container, false);
//————————your own implementation—————————————————————————
return view;
}
public static class FragmentScreenshots extends RowsSupportFragment {
private ArrayObjectAdapter mRowsAdapter = null;
public FragmentScreenshots() {
mRowsAdapter = new ArrayObjectAdapter(new ShadowRowPresenterSelector());
setAdapter(mRowsAdapter);
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//———————Provide data accordinally———————————
List<ScreenshotItem> list;
// Add a Related items row
ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(
new ScreenshotCardPresenter(getActivity()));
for (ScreenshotItem s:list)
{
listRowAdapter.add(s);
}
HeaderItem header = new HeaderItem("Screenshots");
mRowsAdapter.add(new ListRow(header, listRowAdapter));
setAdapter(mRowsAdapter);
setOnItemViewClickedListener(new OnItemViewClickedListener() {
#Override
public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item, RowPresenter.ViewHolder rowViewHolder, Row row) {
if (item instanceof ScreenshotItem) {
}
else{
}
}
});
setOnItemViewSelectedListener(new OnItemViewSelectedListener() {
#Override
public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item, RowPresenter.ViewHolder rowViewHolder, Row row) {
}
});
}
#Override
public void setExpand(boolean expand) {
super.setExpand(true);
}
#Override
public void setOnItemViewClickedListener(BaseOnItemViewClickedListener listener) {
super.setOnItemViewClickedListener(listener);
}
#Override
public void setOnItemViewSelectedListener(BaseOnItemViewSelectedListener listener) {
super.setOnItemViewSelectedListener(listener);
}
}}
You have to use BrowseFragment for your purpose. It is composed of a RowsFragment and a HeadersFragment.
A BrowseFragment renders the elements of its ObjectAdapter as a set of rows in a vertical list. The elements in this adapter must be subclasses of Row.
This tutorial can help you to get started.
i have a simple recycler view which contains card views with only 1 imageView inside, which is loading from resources, but i have strong lags while scrolling anyway, i tried recycler.setHasFixedSize(true) but it doesn't help.
Acitivity code
public class MainActivity extends AppCompatActivity {
private final int[] drawables = {
R.drawable.nxt_bluetooth_dongle,
R.drawable.color_sensor,
R.drawable.connector_cabels,
R.drawable.e_motor,
R.drawable.energy_storage,
R.drawable.energy_display,
R.drawable.gyroscopic_sensor,
R.drawable.intelligent_nxt_brick,
R.drawable.keyfob_transponder,
R.drawable.light_sensor,
R.drawable.motion_sensor,
R.drawable.nxt_ir_receiver,
R.drawable.nxt_light_sensor,
R.drawable.nxt_servo_motor,
R.drawable.nxt_sound_sensor,
R.drawable.nxt_touch_sensor,
R.drawable.nxt_ultrasonic_sensor,
R.drawable.rf_id_sensor,
R.drawable.solar_panel,
R.drawable.tilt_sensor,
R.drawable.temperature_sensor,
R.drawable.usb_hub
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RecyclerView recycler = (RecyclerView) findViewById(R.id.recycler);
MyAdapter adapter = new MyAdapter(drawables);
recycler.setAdapter(adapter);
recycler.setLayoutManager(new GridLayoutManager(this, 3));
}
private class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyHolder> {
private int[] drawables;
private MyAdapter(int[] drawables) {
this.drawables = drawables;
}
#Override
public MyHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.lego_recycler_item, null, false);
return new MyHolder(view);
}
#Override
public void onBindViewHolder(MyHolder holder, int position) {
holder.legoImage.setImageResource(drawables[position]);
}
#Override
public int getItemCount() {
return drawables.length;
}
class MyHolder extends RecyclerView.ViewHolder {
ImageView legoImage;
MyHolder(View itemView) {
super(itemView);
legoImage = (ImageView) itemView.findViewById(R.id.legoImage);
legoImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this, LegoDetailActivity.class);
intent.putExtra(LegoDetailActivity.EXTRA_DRAWABLE_ID, drawables[getAdapterPosition()]);
ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(
MainActivity.this, legoImage, "legoDetail"
);
startActivity(intent, options.toBundle());
}
});
}
}
}
}
Activity xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/recycler"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#e0e0e0"
tools:context="com.lol.legomindstorms.MainActivity">
</android.support.v7.widget.RecyclerView>
Recycler item xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
app:cardUseCompatPadding="true"
app:cardCornerRadius="0dp">
<ImageView
android:id="#+id/legoImage"
android:layout_width="115dp"
android:layout_height="115dp"
android:transitionName="legoDetail" />
</android.support.v7.widget.CardView>
Well as Per my Experience i think the problem is in loading multiple Images
As android do have problem with loading lots of images in memory ,
as android by default does not allow lot of gc memeory size ,
Check out your logs do you get a gc memory over load error
or something similar to that
1.you can Also try chaning the heap size
2.Try using an external library it is always said never reinvent the wheel
try glide or piccaso
3.Try clearing bitmap memory by your self
PS: i am not that writter so please dont mind if my wording were bad but i have dealt with these issues a lot so i am very familar with this problem
I'm trying the two new features in android L version,
RecyclerView
CardView
Well the RecyclerView got working fine for me.But when I tried to execute the CardView.It throws an error and I was not able to find whats the error is!
MainActivity.java
public class MainActivity extends Activity {
private RecyclerView mRecyclerView;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String[] myDataset ={"Uday","Harihar","chetan","ravi","harish","Rahul","satish","vikaram","ravikiran","harish2"};
mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
// improve performance if you know that changes in content
// do not change the size of the RecyclerView
mRecyclerView.setHasFixedSize(true);
// use a linear layout manager
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
// specify an adapter (see also next example)
mAdapter = new MyAdapter(myDataset);
mRecyclerView.setAdapter(mAdapter);
}
MyAdapter.java
package com.hrh.material;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private String[] mDataset;
// Provide a reference to the views for each data item
// Complex data items may need more than one view per item, and
// you provide access to all the views for a data item in a view holder
public static class ViewHolder extends RecyclerView.ViewHolder {
// each data item is just a string in this case
public TextView mTextView;
public ViewHolder(View v) {
super(v);
mTextView = (TextView)v.findViewById(R.id.text);
}
}
// Provide a suitable constructor (depends on the kind of dataset)
public MyAdapter(String[] myDataset) {
mDataset = myDataset;
}
// Create new views (invoked by the layout manager)
#Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
// create a new view
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.activity_card_view, parent, false);
// set the view's size, margins, paddings and layout parameters
ViewHolder vh = new ViewHolder(v);
return vh;
}
// Replace the contents of a view (invoked by the layout manager)
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
// - get element from your dataset at this position
// - replace the contents of the view with that element
holder.mTextView.setText(mDataset[position]);
}
// Return the size of your dataset (invoked by the layout manager)
#Override
public int getItemCount() {
return mDataset.length;
}
}
activity_card_view.xml
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_height="match_parent"
android:layout_width="match_parent"
>
<android.support.v7.widget.CardView
android:id="#+id/cardview"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:elevation="100dp"
card_view:cardCornerRadius="8dp"
>
<TextView
android:id="#+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</android.support.v7.widget.CardView>
</RelativeLayout>
in the layout it shows that "Resource id 0x7f040001 is not of type STYLE (instead anim)".
I resolve the issue following this steps:
Removing the android-support-v7-appcompat, and cardview libs projects from my IDE (Eclipse in my case).
Update Android SDK Tools and Android Support Library from Android SDK Manager.
Restart your IDE (Eclipse).
Import the android-support-v7-appcompat, and cardview libs projects.
And make sure you added xmlns:card_view at the top of your your xml file:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
<android.support.v7.widget.CardView
android:id="#+id/card_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
card_view:cardCornerRadius="4dp">
And thats it , hope it helps.
i am also facing same error,i found solution for this just remove two packages from sdk and install again.They are Extras->android support repository and android support library