I've got a Fragment, which has a RecyclerView. This RecyclerView has a header adapter, which contains an EditText.
When the Fragment comes into view, I want the EditText to auto focus (i.e. show the keyboard automatically).
How would I do this?
The Fragment:
public class My Fragment extends Fragment {
private LinearLayoutManager layoutManager;
private FeedRecyclerView recyclerView;
private PostAdapter postAdapter;
private ConcatAdapter concatAdapter;
private HeaderAdapter headerAdapter;
private List<Post> postData = new ArrayList<>();
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
return inflater.inflate(R.layout.my_fragment, parent, false);
}
#Override
public void onViewCreated(#NonNull View view, Bundle savedInstanceState) {
recyclerView = view.findViewById(R.id.recycler_view);
layoutManager = new FeedLinearLayoutManager(getContext());
recyclerView.setLayoutManager(layoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
// This is the adapter that contains the EditText
headerAdapter = new HeaderAdapter(getContext());
postAdapter = new PostAdapter(getContext(), postData, layoutManager);
concatAdapter = new ConcatAdapter();
recyclerView.setAdapter(concatAdapter);
concatAdapter.addAdapter(searchHeaderAdapter);
}
}
The adapter class, HeaderAdapter:
public class HeaderAdapter extends RecyclerView.Adapter<HeaderAdapter.ViewHolder> {
private Context context;
public HeaderAdapter(Context context) {
this.context = context;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.my_header, parent, false));
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
//
}
#Override
public long getItemId(int position) {
return 1;
}
#Override
public int getItemCount() {
return 1;
}
public class ViewHolder extends RecyclerView.ViewHolder {
public EditText myEditText;
public ViewHolder(View v) {
super(v);
myEditText = v.findViewById(R.id.my_edit_text);
}
}
}
As you can see, my RecyclerView's adapter, HeaderAdapter, has the EditText. When the Fragment gets shown, I want to auto focus this EditText.
How would I do this?
Thanks!
Add this line myEditText.requestFocus() into init in Header ViewHolder
init {
myEditText = v.findViewById(R.id.my_edit_text)
myEditText.requestFocus()
}
try this
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
holder.myEditText.requestFocus();
((InputMethodManager)holder.itemView.context.getSystemService(Context.INPUT_METHOD_SERVICE)).showSoftInput(holder.myEditText, 0);
}
Related
I'm trying to start a new Fragment that shows the details of the item that was clicked on in the RecyclerView. The RecyclerView is on a Fragments. I've tried this in Activities and it worked perfectly but I'm trying to convert it to use on Fragments. And Also, how to detect other gestures in the RecyclerView (swipe, etc...)
My Adapter :
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
private final ArrayList<Tip> dataSet;
public static class MyViewHolder extends RecyclerView.ViewHolder {
TextView textViewTitle;
TextView textViewType;
//TextView textViewDetail;
ImageView imageViewImage;
public MyViewHolder(View itemView) {
super(itemView);
this.textViewTitle = itemView.findViewById(R.id.title);
this.textViewType = itemView.findViewById(R.id.type);
//this.textViewDetail = itemView.findViewById(R.id.detail);
this.imageViewImage = itemView.findViewById(R.id.itemImage);
}
}
public MyAdapter(ArrayList<Tip> data) {
this.dataSet = data;
}
#NonNull
#Override
public MyAdapter.MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate( R.layout.item, parent, false);
view.setOnClickListener(HomeFragment.myOnClickListener);
MyViewHolder myViewHolder = new MyViewHolder(view);
return myViewHolder;
}
#Override
public void onBindViewHolder(#NonNull MyAdapter.MyViewHolder holder, int listPosition) {
TextView textViewTitle = holder.textViewTitle;
TextView textViewType = holder.textViewType;
//TextView textViewDetail = holder.textViewDetail;
ImageView imageViewImage = holder.imageViewImage;
textViewTitle.setText( dataSet.get(listPosition).getTitle() );
textViewType.setText( dataSet.get(listPosition).getType() );
//textViewDetail.setText( dataSet.get(listPosition).getDetail() );
imageViewImage.setImageResource( dataSet.get(listPosition).getImage() );
}
#Override
public int getItemCount() {
return dataSet.size();
}
}
My Fragment :
public class HomeFragment extends Fragment {
public static RecyclerView.Adapter myAdapter;
private static RecyclerView.LayoutManager myLayoutManager;
private static RecyclerView myRecyclerView;
public static View.OnClickListener myOnClickListener;
private static ArrayList<Tip> myData;
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Get the integer from the integers.xml resource file
Resources res = getResources();
int gridColumnCount = res.getInteger(R.integer.grid_column_count);
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_home, container, false);
// Add the following lines to create RecyclerView
myRecyclerView = view.findViewById(R.id.my_recycler_view);
myRecyclerView.setHasFixedSize(true);
//myLayoutManager = new LinearLayoutManager( view.getContext() );
myLayoutManager = new GridLayoutManager( view.getContext(),gridColumnCount );
myRecyclerView.setLayoutManager( myLayoutManager );
myRecyclerView.setItemAnimator( new DefaultItemAnimator() );
myData = new ArrayList<Tip>();
for (int i = 0; i < MyData.tipTitleArray.length; i++) {
myData.add(new Tip( MyData.tipTitleArray[i], MyData.tipTypeArray[i], MyData.tipDetailArray[i], MyData.id_[i], MyData.tipImageArray[i] ));
}
myAdapter = new MyAdapter(myData);
myRecyclerView.setAdapter(myAdapter);
//On retourne la View
return view;
}
#Override
public void onDestroyView() {
super.onDestroyView();
fr.cnam.smb116.mimi_tips_navdraw.databinding.FragmentHomeBinding binding = null;
}
}
Don't use static listener and recyclerview instance.
Better to add callBack function to handle this.
e.g
interface RecyclerViewItemClickListener<T> {
void onClick(int position, T data);
}
init property in your adapter
RecyclerViewItemClickListener<Tip> listener
constructor of your Adapter
MyAdapter(RecyclerViewItemClickListener<Tip> listener) {
this. listener = listener
}
in
onBindViewHolder() {
holder.setOnClickListener(v -> {
listener.onClick(position, dataSet.get(listPosition));
})
}
In Your Fragment
Implement this interface
public class HomeFragment extends Fragment implements RecyclerViewItemClickListener<Tip> {
}
your adapter instance
myAdapter = new MyAdapter(myData,this);
implement onClick Method in your fragment
void onClick(int position, Tip tip){
// your listener
}
I have a nested recyclerview, and I just want it to display different item numbers for each item of the parent recyclerview.
It's supposed that each item implements number of view according to each model object list that's been passed to adapter
It may look like as the layout shown in this image
Here is my parent adapter code
public class ConstructionAdapter extends RecyclerView.Adapter<ConstructionAdapter.ConstructionViewHolder> {
private RecyclerView.RecycledViewPool viewPool = new RecyclerView.RecycledViewPool();
private final List<ConstructionModel> constructionList;
public ConstructionAdapter(List<ConstructionModel> constructionList) {
this.constructionList = constructionList;
}
#NonNull
#Override
public ConstructionViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.construction_cranes_view_item, parent, false);
return new ConstructionViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ConstructionViewHolder holder, int position) {
holder.setContent(constructionList.get(position));
}
#Override
public int getItemCount() {
return constructionList.size();
}
public class ConstructionViewHolder extends RecyclerView.ViewHolder {
private TextView categoeyTitleTV;
private RecyclerView constructionRecyclerView;
private ConstructionViewHolder(#NonNull View itemView) {
super(itemView);
categoeyTitleTV = itemView.findViewById(R.id.category_title_tv);
constructionRecyclerView = itemView.findViewById(R.id.construction_item_recycler);
}
private void setContent(ConstructionModel model) {
LinearLayoutManager layoutManager = new LinearLayoutManager(itemView.getContext());
constructionRecyclerView.setLayoutManager(layoutManager);
categoeyTitleTV.setText(model.getCraneCategory());
layoutManager.setInitialPrefetchItemCount(model.getSubCategoryList().size());
IndustrialCranesAdapter subCatAdapter = new IndustrialCranesAdapter(model.getSubCategoryList());
constructionRecyclerView.setAdapter(subCatAdapter);
constructionRecyclerView.setRecycledViewPool(viewPool);
}
}
}
Here is my Inner recyclerview adapter
public class IndustrialCranesAdapter extends RecyclerView.Adapter<IndustrialCranesAdapter.IndustrialCranesViewHolder> {
private final List<Crane> industrialCranesList;
public IndustrialCranesAdapter(List<Crane> industrialCranesList) {
this.industrialCranesList = industrialCranesList;
}
#NonNull
#Override
public IndustrialCranesViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.crane_item, parent, false);
return new IndustrialCranesViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull IndustrialCranesViewHolder holder, int position) {
holder.setCranesItems(industrialCranesList.get(position));
}
#Override
public int getItemCount() {
return industrialCranesList.size();
}
public class IndustrialCranesViewHolder extends RecyclerView.ViewHolder {
private TextView craneTitle;
private ImageView craneImage;
private IndustrialCranesViewHolder(#NonNull View itemView) {
super(itemView);
craneTitle = itemView.findViewById(R.id.industrial_crane_title);
craneImage = itemView.findViewById(R.id.industrial_crane_image_view);
itemView.getRootView().setOnClickListener(v->{
Toast.makeText(itemView.getContext(), "Clicked", Toast.LENGTH_SHORT).show();
});
}
private void setCranesItems(Crane crane){
craneTitle.setText(crane.getCraneTitle());
craneImage.setImageResource(crane.getCraneImage());
}
}
}
I have an abstract base fragment class that extends from fragment. Monitor list fragment extend from this base fragment. I need to set individual adapters in each fragment because the data in the fragments are different. Problem is, the monitor list fragment only returns 1 fragment with no data?
In BaseFragment
public abstract class BaseFragment extends Fragment {
private ArrayList<CholesterolMonitor> objectList;
private int mColumnCount = 1;
public void setObjectList(String listKey){
if (getArguments()!=null){
this.objectList= getArguments().getParcelableArrayList(listKey);
}
#Override
public View onCreateView(LayoutInflater inflater,ViewGroup parent, Bundle savedInstanseState)
{
View view = provideYourFragmentView(inflater,parent,savedInstanseState);
// Set to recycler view
if (view instanceof RecyclerView) {
Context context = view.getContext();
RecyclerView recyclerView = (RecyclerView) view;
if (mColumnCount <= 1) {
recyclerView.setLayoutManager(new LinearLayoutManager(context));
} else {
recyclerView.setLayoutManager(new GridLayoutManager(context, mColumnCount));
}
}
return view;
}
}
In monitor list fragment
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = super.onCreateView(inflater, container,
savedInstanceState);
//Set individual adapter
monitor_list = getObjectList();
if (v instanceof RecyclerView) {
RecyclerView recyclerView = (RecyclerView) v;
adapter = new MonitorListRecyclerAdapter(monitor_list, this.getContext());
recyclerView.setAdapter(adapter);
}
return v;
}
I found out that the layout I inflated in XML should be a RecyclerView type.
Maybe you can use a abstract method to create Adapter
This may not resolve your problem, but you can do your adapter logic in your sub fragment class, this way will be more clearly
public abstract class BaseFragment extends Fragment {
private ArrayList<CholesterolMonitor> objectList;
private int mColumnCount = 1;
public void setObjectList(String listKey){
if (getArguments()!=null){
this.objectList= getArguments().getParcelableArrayList(listKey);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanseState)
{
View view = provideYourFragmentView(inflater, parent, savedInstanseState);
// Set to recycler view
if (view instanceof RecyclerView) {
Context context = view.getContext();
RecyclerView recyclerView = (RecyclerView) view;
if (mColumnCount <= 1) {
recyclerView.setLayoutManager(new LinearLayoutManager(context));
} else {
recyclerView.setLayoutManager(new GridLayoutManager(context, mColumnCount));
}
recyclerView.setAdapter(this.createAdapter());
}
return view;
}
abstract <ViewHolderT extends RecyclerView.ViewHolder, AdapterT extends RecyclerView.Adapter<ViewHolderT>> AdapterT createAdapter();
}
SubFragmentA
public class SubFragmentA extends BaseFragment {
#Override
SubAdapterA createAdapter() {
return new SubAdapterA();
}
public static class SubAdapterA extends RecyclerView.Adapter<SubViewHolderA> {
#NonNull
#Override
public SubViewHolderA onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
return null;
}
#Override
public void onBindViewHolder(#NonNull SubViewHolderA subViewHolder, int i) {
}
#Override
public int getItemCount() {
return 0;
}
}
public static class SubViewHolderA extends RecyclerView.ViewHolder {
public SubViewHolderA(#NonNull View itemView) {
super(itemView);
}
}
}
SubFragmentB
public class SubFragmentB extends BaseFragment {
#Override
SubAdapterB createAdapter() {
return new SubAdapterB();
}
public static class SubAdapterB extends RecyclerView.Adapter<SubViewHolderB> {
#NonNull
#Override
public SubViewHolderB onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
return null;
}
#Override
public void onBindViewHolder(#NonNull SubViewHolderB subViewHolder, int i) {
}
#Override
public int getItemCount() {
return 0;
}
}
public static class SubViewHolderB extends RecyclerView.ViewHolder {
public SubViewHolderB(#NonNull View itemView) {
super(itemView);
}
}
}
If you got multiple ViewHolder Type you can do like this
public static class BaseViewHolder extends RecyclerView.ViewHolder {
protected TextView commonTextView;
public BaseViewHolder(#NonNull View itemView) {
super(itemView);
//init commonTextView;
}
}
public static class SubViewHolderB extends BaseViewHolder {
private TextView textViewB;
public SubViewHolderB(#NonNull View itemView) {
super(itemView);
//init textViewB
}
public void bindData(DataModelB data) {
commonTextView.setText("Common text set Integer data :" + data.intField);
textViewB.setText("This is Integer :" + data.intField);
}
}
public static class SubViewHolderA extends BaseViewHolder {
private TextView textViewA;
public SubViewHolderA(#NonNull View itemView) {
super(itemView);
//init textViewB
}
public void bindData(DataModelA data) {
commonTextView.setText("Common text set String data :" + data.strField);
textViewA.setText("This is String :" + data.strField);
}
}
public static class DataModelB {
int intField;
}
public static class DataModelA {
String strField;
}
In my SectionsListAdapter adapter i have nested Adapter named MonthLessonsList, after get date from web service and set new data and call notifyDataSetChanged method for adapter, main adapter as SectionsListAdapter can be refresh, but nested adapter dont refresh and after calling notifyDataSetChanged for that, doesn't work correctly and don't show new data
call and set new data from Fragment:
monthSectionsItems = SQLite.select().from(MonthSections.class).queryList();
adapter.setData(monthSectionsItems);
and my Adapter with nested adapter:
public class SectionsListAdapter extends RecyclerView.Adapter<SectionsListAdapter.MyViewHolder> {
private final OnItemSelected listener;
private List<MonthSections> list;
private Context context;
private MonthLessonsList lessonsListAdapter;
public SectionsListAdapter(List<MonthSections> followingsList, Context mContext, OnItemSelected listener) {
this.list = followingsList;
this.context = mContext;
this.listener = listener;
}
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.sections_list_row, parent, false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(#NonNull final MyViewHolder holder, final int position) {
holder.indicatorIcon.setText(list.get(position).getSection_month_name());
...
List<SectionLesson> lessonsList = list.get(position).getLessons();
lessonsListAdapter = new MonthLessonsList(lessonsList);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(context);
holder.userChildCategories.setLayoutManager(mLayoutManager);
holder.userChildCategories.setAdapter(lessonsListAdapter);
...
}
#Override
public int getItemCount() {
return list.size();
}
public void setData(List<MonthSections> data) {
list.clear();
list.addAll(data);
notifyDataSetChanged();
lessonsListAdapter.notifyDataSetChanged();
}
public List<MonthSections> getData() {
return list;
}
class MyViewHolder extends RecyclerView.ViewHolder {
...
public MyViewHolder(View view) {
super(view);
ButterKnife.bind(this, view);
section_title.setGravity(Gravity.RIGHT);
}
}
public class MonthLessonsList extends RecyclerView.Adapter<MonthLessonsList.LessonsViewHolder> {
private List<SectionLesson> lessonItem;
public class LessonsViewHolder extends RecyclerView.ViewHolder {
public TextView title;
public LessonsViewHolder(View view) {
super(view);
title = view.findViewById(R.id.title);
}
}
public MonthLessonsList(List<SectionLesson> lists) {
this.lessonItem = lists;
}
#Override
public LessonsViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.child_list_row, parent, false);
return new LessonsViewHolder(itemView);
}
#SuppressLint("SetTextI18n")
#Override
public void onBindViewHolder(#NonNull LessonsViewHolder holder, int position) {
SectionLesson lesson = lessonItem.get(position);
holder.title.setText("درس: " + (position + 1) + ") " + lesson.getTitle());
}
#Override
public int getItemCount() {
return lessonItem.size();
}
}
}
Declare child adapter inside onBindViewHolder, and remove from global level.
And no need to notify child adapter. Because that will be automatically filled when parent onBindViewHolder is called.
Like
MonthLessonsList lessonsListAdapter = new MonthLessonsList(lessonsList);
holder.userChildCategories.setAdapter(lessonsListAdapter);
I want to grey out fragment activity on some condition, I am trying to set a flag in pojo class and checking every time i try to grey out an activity.
I do not know where exactly the logic should be placed. I tried to put it inside a onCreateView() method, but it gave me an null pointer exception.
Please find the code below for your reference.
#SuppressLint("ValidFragment")
public class QuizTab extends Fragment {
private static final String TAG = "QuizTab";
RecyclerView recyclerView;
View view;
LinearLayout linearLayout;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
view = inflater.inflate(R.layout.quiztab, container, false);
recyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
if(flag){
grey out logic ---- not working
}
getQuizContent();
setupRecyclerView(recyclerView);
return view;
}
private void setupRecyclerView(RecyclerView recyclerView) {
recyclerView.setLayoutManager(new LinearLayoutManager(recyclerView.getContext()));
recyclerView.setAdapter(new SimpleStringRecyclerViewAdapter(getActivity()));
}
public class SimpleStringRecyclerViewAdapter extends RecyclerView.Adapter<SimpleStringRecyclerViewAdapter.ViewHolder> {
private Context mContext;
public class ViewHolder extends RecyclerView.ViewHolder {
public final LinearLayout mLinearlayout;
public ViewHolder(View view) {
super(view);
mLinearlayout = (LinearLayout) view.findViewById(R.id.mcq);
}
}
public SimpleStringRecyclerViewAdapter(Context context) {
mContext = context;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.quiztab_mcq, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
}
#Override
public int getItemCount() {
return 1;
}
}
}
LinearLayout in this case is parent of fragment i tryed to paint fragment but failure so i did something like that
if(flag){
LinearLayout layout = view.findViewById(R.id.parentOffragment);
layout.setBackgroundColor(Color.GRAY);
}